openbolt 5.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Puppetfile +52 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +60 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/containerresult.rb +51 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/future.rb +25 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +71 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +55 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +65 -0
- data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +93 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +33 -0
- data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +38 -0
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +208 -0
- data/bolt-modules/boltlib/lib/puppet/functions/background.rb +62 -0
- data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +57 -0
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +130 -0
- data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +31 -0
- data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +52 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +87 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +34 -0
- data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +35 -0
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +74 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +97 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +47 -0
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +52 -0
- data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +40 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +42 -0
- data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +53 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +106 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_container.rb +162 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +291 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +145 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +164 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +211 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +48 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +43 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +145 -0
- data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +38 -0
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +101 -0
- data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +29 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait.rb +131 -0
- data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +59 -0
- data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +39 -0
- data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +50 -0
- data/bolt-modules/boltlib/types/planresult.pp +18 -0
- data/bolt-modules/boltlib/types/targetspec.pp +7 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +42 -0
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +20 -0
- data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +35 -0
- data/bolt-modules/file/lib/puppet/functions/file/delete.rb +21 -0
- data/bolt-modules/file/lib/puppet/functions/file/exists.rb +28 -0
- data/bolt-modules/file/lib/puppet/functions/file/join.rb +20 -0
- data/bolt-modules/file/lib/puppet/functions/file/read.rb +33 -0
- data/bolt-modules/file/lib/puppet/functions/file/readable.rb +28 -0
- data/bolt-modules/file/lib/puppet/functions/file/write.rb +24 -0
- data/bolt-modules/log/lib/puppet/functions/log/debug.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/error.rb +40 -0
- data/bolt-modules/log/lib/puppet/functions/log/fatal.rb +40 -0
- data/bolt-modules/log/lib/puppet/functions/log/info.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/trace.rb +39 -0
- data/bolt-modules/log/lib/puppet/functions/log/warn.rb +41 -0
- data/bolt-modules/out/lib/puppet/functions/out/message.rb +36 -0
- data/bolt-modules/out/lib/puppet/functions/out/verbose.rb +35 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt/menu.rb +103 -0
- data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +65 -0
- data/bolt-modules/system/lib/puppet/functions/system/env.rb +20 -0
- data/exe/bolt +17 -0
- data/guides/debugging.yaml +27 -0
- data/guides/inventory.yaml +23 -0
- data/guides/links.yaml +12 -0
- data/guides/logging.yaml +17 -0
- data/guides/module.yaml +18 -0
- data/guides/modulepath.yaml +24 -0
- data/guides/project.yaml +21 -0
- data/guides/targets.yaml +28 -0
- data/guides/transports.yaml +22 -0
- data/lib/bolt/analytics.rb +233 -0
- data/lib/bolt/application.rb +806 -0
- data/lib/bolt/applicator.rb +368 -0
- data/lib/bolt/apply_inventory.rb +93 -0
- data/lib/bolt/apply_result.rb +154 -0
- data/lib/bolt/apply_target.rb +90 -0
- data/lib/bolt/bolt_option_parser.rb +1226 -0
- data/lib/bolt/catalog/logging.rb +15 -0
- data/lib/bolt/catalog.rb +144 -0
- data/lib/bolt/cli.rb +949 -0
- data/lib/bolt/config/modulepath.rb +30 -0
- data/lib/bolt/config/options.rb +673 -0
- data/lib/bolt/config/transport/base.rb +133 -0
- data/lib/bolt/config/transport/docker.rb +34 -0
- data/lib/bolt/config/transport/jail.rb +33 -0
- data/lib/bolt/config/transport/local.rb +39 -0
- data/lib/bolt/config/transport/lxd.rb +34 -0
- data/lib/bolt/config/transport/options.rb +431 -0
- data/lib/bolt/config/transport/orch.rb +41 -0
- data/lib/bolt/config/transport/podman.rb +33 -0
- data/lib/bolt/config/transport/remote.rb +24 -0
- data/lib/bolt/config/transport/ssh.rb +138 -0
- data/lib/bolt/config/transport/winrm.rb +63 -0
- data/lib/bolt/config.rb +515 -0
- data/lib/bolt/container_result.rb +105 -0
- data/lib/bolt/error.rb +194 -0
- data/lib/bolt/executor.rb +539 -0
- data/lib/bolt/fiber_executor.rb +190 -0
- data/lib/bolt/inventory/group.rb +446 -0
- data/lib/bolt/inventory/inventory.rb +391 -0
- data/lib/bolt/inventory/options.rb +139 -0
- data/lib/bolt/inventory/target.rb +293 -0
- data/lib/bolt/inventory.rb +120 -0
- data/lib/bolt/logger.rb +252 -0
- data/lib/bolt/module.rb +54 -0
- data/lib/bolt/module_installer/installer.rb +44 -0
- data/lib/bolt/module_installer/puppetfile/forge_module.rb +54 -0
- data/lib/bolt/module_installer/puppetfile/git_module.rb +37 -0
- data/lib/bolt/module_installer/puppetfile/module.rb +26 -0
- data/lib/bolt/module_installer/puppetfile.rb +131 -0
- data/lib/bolt/module_installer/resolver.rb +129 -0
- data/lib/bolt/module_installer/specs/forge_spec.rb +91 -0
- data/lib/bolt/module_installer/specs/git_spec.rb +150 -0
- data/lib/bolt/module_installer/specs/id/base.rb +116 -0
- data/lib/bolt/module_installer/specs/id/gitclone.rb +120 -0
- data/lib/bolt/module_installer/specs/id/github.rb +90 -0
- data/lib/bolt/module_installer/specs/id/gitlab.rb +92 -0
- data/lib/bolt/module_installer/specs.rb +95 -0
- data/lib/bolt/module_installer.rb +208 -0
- data/lib/bolt/node/errors.rb +55 -0
- data/lib/bolt/node/output.rb +29 -0
- data/lib/bolt/outputter/human.rb +958 -0
- data/lib/bolt/outputter/json.rb +205 -0
- data/lib/bolt/outputter/logger.rb +76 -0
- data/lib/bolt/outputter/rainbow.rb +118 -0
- data/lib/bolt/outputter.rb +57 -0
- data/lib/bolt/pal/issues.rb +19 -0
- data/lib/bolt/pal/logging.rb +17 -0
- data/lib/bolt/pal/yaml_plan/evaluator.rb +83 -0
- data/lib/bolt/pal/yaml_plan/loader.rb +94 -0
- data/lib/bolt/pal/yaml_plan/parameter.rb +63 -0
- data/lib/bolt/pal/yaml_plan/step/command.rb +45 -0
- data/lib/bolt/pal/yaml_plan/step/download.rb +37 -0
- data/lib/bolt/pal/yaml_plan/step/eval.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/message.rb +31 -0
- data/lib/bolt/pal/yaml_plan/step/plan.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/resources.rb +170 -0
- data/lib/bolt/pal/yaml_plan/step/script.rb +62 -0
- data/lib/bolt/pal/yaml_plan/step/task.rb +42 -0
- data/lib/bolt/pal/yaml_plan/step/upload.rb +37 -0
- data/lib/bolt/pal/yaml_plan/step/verbose.rb +31 -0
- data/lib/bolt/pal/yaml_plan/step.rb +223 -0
- data/lib/bolt/pal/yaml_plan/transpiler.rb +90 -0
- data/lib/bolt/pal/yaml_plan.rb +172 -0
- data/lib/bolt/pal.rb +847 -0
- data/lib/bolt/plan_creator.rb +219 -0
- data/lib/bolt/plan_future.rb +86 -0
- data/lib/bolt/plan_result.rb +44 -0
- data/lib/bolt/plugin/cache.rb +76 -0
- data/lib/bolt/plugin/env_var.rb +54 -0
- data/lib/bolt/plugin/module.rb +276 -0
- data/lib/bolt/plugin/prompt.rb +36 -0
- data/lib/bolt/plugin/puppet_connect_data.rb +84 -0
- data/lib/bolt/plugin/puppetdb.rb +124 -0
- data/lib/bolt/plugin/task.rb +72 -0
- data/lib/bolt/plugin.rb +380 -0
- data/lib/bolt/project.rb +219 -0
- data/lib/bolt/project_manager/config_migrator.rb +113 -0
- data/lib/bolt/project_manager/inventory_migrator.rb +67 -0
- data/lib/bolt/project_manager/migrator.rb +39 -0
- data/lib/bolt/project_manager/module_migrator.rb +203 -0
- data/lib/bolt/project_manager.rb +221 -0
- data/lib/bolt/puppetdb/client.rb +153 -0
- data/lib/bolt/puppetdb/config.rb +176 -0
- data/lib/bolt/puppetdb/instance.rb +146 -0
- data/lib/bolt/puppetdb.rb +15 -0
- data/lib/bolt/r10k_log_proxy.rb +30 -0
- data/lib/bolt/rerun.rb +55 -0
- data/lib/bolt/resource_instance.rb +133 -0
- data/lib/bolt/result.rb +247 -0
- data/lib/bolt/result_set.rb +128 -0
- data/lib/bolt/shell/bash/tmpdir.rb +62 -0
- data/lib/bolt/shell/bash.rb +516 -0
- data/lib/bolt/shell/powershell/snippets.rb +181 -0
- data/lib/bolt/shell/powershell.rb +365 -0
- data/lib/bolt/shell.rb +105 -0
- data/lib/bolt/target.rb +174 -0
- data/lib/bolt/task/puppet_server.rb +27 -0
- data/lib/bolt/task/run.rb +55 -0
- data/lib/bolt/task.rb +163 -0
- data/lib/bolt/transport/base.rb +252 -0
- data/lib/bolt/transport/docker/connection.rb +150 -0
- data/lib/bolt/transport/docker.rb +23 -0
- data/lib/bolt/transport/jail/connection.rb +81 -0
- data/lib/bolt/transport/jail.rb +21 -0
- data/lib/bolt/transport/local/connection.rb +106 -0
- data/lib/bolt/transport/local.rb +20 -0
- data/lib/bolt/transport/lxd/connection.rb +115 -0
- data/lib/bolt/transport/lxd.rb +26 -0
- data/lib/bolt/transport/orch/connection.rb +111 -0
- data/lib/bolt/transport/orch.rb +271 -0
- data/lib/bolt/transport/podman/connection.rb +102 -0
- data/lib/bolt/transport/podman.rb +19 -0
- data/lib/bolt/transport/remote.rb +41 -0
- data/lib/bolt/transport/simple.rb +54 -0
- data/lib/bolt/transport/ssh/connection.rb +321 -0
- data/lib/bolt/transport/ssh/exec_connection.rb +140 -0
- data/lib/bolt/transport/ssh.rb +48 -0
- data/lib/bolt/transport/winrm/connection.rb +378 -0
- data/lib/bolt/transport/winrm.rb +33 -0
- data/lib/bolt/util/format.rb +68 -0
- data/lib/bolt/util/puppet_log_level.rb +21 -0
- data/lib/bolt/util.rb +465 -0
- data/lib/bolt/validator.rb +227 -0
- data/lib/bolt/version.rb +5 -0
- data/lib/bolt.rb +8 -0
- data/lib/bolt_server/acl.rb +39 -0
- data/lib/bolt_server/base_config.rb +112 -0
- data/lib/bolt_server/config.rb +64 -0
- data/lib/bolt_server/file_cache.rb +200 -0
- data/lib/bolt_server/request_error.rb +11 -0
- data/lib/bolt_server/schemas/action-check_node_connections.json +14 -0
- data/lib/bolt_server/schemas/action-run_command.json +12 -0
- data/lib/bolt_server/schemas/action-run_script.json +47 -0
- data/lib/bolt_server/schemas/action-run_task.json +20 -0
- data/lib/bolt_server/schemas/action-upload_file.json +47 -0
- data/lib/bolt_server/schemas/partials/target-any.json +10 -0
- data/lib/bolt_server/schemas/partials/target-ssh.json +88 -0
- data/lib/bolt_server/schemas/partials/target-winrm.json +67 -0
- data/lib/bolt_server/schemas/partials/task.json +94 -0
- data/lib/bolt_server/schemas/transport-ssh.json +25 -0
- data/lib/bolt_server/schemas/transport-winrm.json +19 -0
- data/lib/bolt_server/transport_app.rb +554 -0
- data/lib/bolt_spec/bolt_context.rb +226 -0
- data/lib/bolt_spec/plans/action_stubs/command_stub.rb +51 -0
- data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
- data/lib/bolt_spec/plans/action_stubs/plan_stub.rb +55 -0
- data/lib/bolt_spec/plans/action_stubs/script_stub.rb +59 -0
- data/lib/bolt_spec/plans/action_stubs/task_stub.rb +57 -0
- data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +65 -0
- data/lib/bolt_spec/plans/action_stubs.rb +196 -0
- data/lib/bolt_spec/plans/mock_executor.rb +361 -0
- data/lib/bolt_spec/plans/publish_stub.rb +49 -0
- data/lib/bolt_spec/plans.rb +190 -0
- data/lib/bolt_spec/run.rb +246 -0
- data/lib/logging_extensions/logging.rb +13 -0
- data/libexec/apply_catalog.rb +130 -0
- data/libexec/bolt_catalog +68 -0
- data/libexec/custom_facts.rb +63 -0
- data/libexec/query_resources.rb +75 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/count.rb +21 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/nodes.rb +22 -0
- data/modules/aggregate/lib/puppet/functions/aggregate/targets.rb +21 -0
- data/modules/aggregate/plans/count.pp +56 -0
- data/modules/aggregate/plans/targets.pp +56 -0
- data/modules/canary/lib/puppet/functions/canary/merge.rb +13 -0
- data/modules/canary/lib/puppet/functions/canary/random_split.rb +22 -0
- data/modules/canary/lib/puppet/functions/canary/skip.rb +25 -0
- data/modules/canary/plans/init.pp +100 -0
- data/modules/puppet_connect/plans/test_input_data.pp +94 -0
- data/modules/puppetdb_fact/plans/init.pp +20 -0
- data/resources/bolt_bash_completion.sh +214 -0
- metadata +735 -0
@@ -0,0 +1,391 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../bolt/inventory/group'
|
4
|
+
require_relative '../../bolt/inventory/target'
|
5
|
+
|
6
|
+
module Bolt
|
7
|
+
class Inventory
|
8
|
+
class Inventory
|
9
|
+
attr_reader :plugins, :source, :targets, :transport
|
10
|
+
|
11
|
+
# Getting targets from the inventory using '--targets' supports extended glob pattern
|
12
|
+
# matching. In this case, use the extended regex so Bolt only uses commas outside
|
13
|
+
# brackets and braces as delimiters.
|
14
|
+
EXTENDED_TARGET_REGEX = /[[:space:],]+(?=[^\]}]*(?:[\[{]|$))/.freeze
|
15
|
+
TARGET_REGEX = /[[:space:],]+/.freeze
|
16
|
+
|
17
|
+
# Pattern which looks for indicators that glob-based target name matching
|
18
|
+
# should be used.
|
19
|
+
GLOB_MATCH_REGEX = /[*?\[\]{}]/.freeze
|
20
|
+
|
21
|
+
class WildcardError < Bolt::Error
|
22
|
+
def initialize(target)
|
23
|
+
super("Found 0 targets matching wildcard pattern #{target}", 'bolt.inventory/wildcard-error')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(data, transport, transports, plugins, source = nil)
|
28
|
+
@logger = Bolt::Logger.logger(self)
|
29
|
+
@data = data || {}
|
30
|
+
@transport = transport
|
31
|
+
@config = transports
|
32
|
+
@config_resolved = transports.values.all?(&:resolved?)
|
33
|
+
@plugins = plugins
|
34
|
+
@targets = {}
|
35
|
+
@source = source
|
36
|
+
end
|
37
|
+
|
38
|
+
def version
|
39
|
+
2
|
40
|
+
end
|
41
|
+
|
42
|
+
def target_implementation_class
|
43
|
+
Bolt::Target
|
44
|
+
end
|
45
|
+
|
46
|
+
# Load and resolve the groups in the inventory. Loading groups resolves
|
47
|
+
# all plugin references except for those for target data and config.
|
48
|
+
#
|
49
|
+
# @return [Bolt::Inventory::Group]
|
50
|
+
#
|
51
|
+
def groups
|
52
|
+
@groups ||= Group.new(@data, @plugins, all_group: true).tap do |groups|
|
53
|
+
groups.resolve_string_targets(groups.target_aliases, groups.all_targets)
|
54
|
+
groups.validate
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return a list of all group names in the inventory.
|
59
|
+
#
|
60
|
+
# @return [Array[String]]
|
61
|
+
#
|
62
|
+
def group_names
|
63
|
+
group_lookup.keys
|
64
|
+
end
|
65
|
+
|
66
|
+
# Return a map of all groups in the inventory.
|
67
|
+
#
|
68
|
+
# @return [Hash[String, Bolt::Inventory::Group]]
|
69
|
+
#
|
70
|
+
def group_lookup
|
71
|
+
@group_lookup ||= groups.collect_groups
|
72
|
+
end
|
73
|
+
|
74
|
+
# Return a map of transport configuration for the inventory. Any
|
75
|
+
# unresolved plugin references are resolved.
|
76
|
+
#
|
77
|
+
# @return [Hash[String, Bolt::Config::Transport]]
|
78
|
+
#
|
79
|
+
def config
|
80
|
+
if @config_resolved
|
81
|
+
@config
|
82
|
+
else
|
83
|
+
@config_resolved = true
|
84
|
+
@config.each_value { |t| t.resolve(@plugins) unless t.resolved? }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def group_names_for(target_name)
|
89
|
+
group_data_for(target_name).fetch('groups', [])
|
90
|
+
end
|
91
|
+
|
92
|
+
def target_names
|
93
|
+
groups.all_targets
|
94
|
+
end
|
95
|
+
# alias for analytics
|
96
|
+
alias node_names target_names
|
97
|
+
|
98
|
+
def get_targets(targets, ext_glob: false)
|
99
|
+
target_array = expand_targets(targets, ext_glob: ext_glob)
|
100
|
+
if target_array.is_a? Array
|
101
|
+
target_array.flatten.uniq(&:name)
|
102
|
+
else
|
103
|
+
[target_array]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def get_target(target)
|
108
|
+
target_array = get_targets(target)
|
109
|
+
if target_array.count > 1
|
110
|
+
raise ValidationError.new("'#{target}' refers to #{target_array.count} targets", nil)
|
111
|
+
end
|
112
|
+
target_array.first
|
113
|
+
end
|
114
|
+
|
115
|
+
#### PRIVATE ####
|
116
|
+
def group_data_for(target_name)
|
117
|
+
groups.group_collect(target_name)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Does a target match the glob-style wildcard?
|
121
|
+
# Ignore case; use extended globs ({a,b}) when running from the CLI.
|
122
|
+
def match_wildcard?(wildcard, target_name, ext_glob: false)
|
123
|
+
if ext_glob
|
124
|
+
File.fnmatch(wildcard, target_name, File::FNM_CASEFOLD | File::FNM_EXTGLOB)
|
125
|
+
else
|
126
|
+
File.fnmatch(wildcard, target_name, File::FNM_CASEFOLD)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# If target is a group name, expand it to the members of that group.
|
131
|
+
# Else match against groups and targets in inventory by name or alias.
|
132
|
+
# Attempt exact matches for groups, targets, and aliases first for speed.
|
133
|
+
# If no exact match and the string contains wildcard characters, then check
|
134
|
+
# and see if the target string might be a URI, if it parses as a URI with
|
135
|
+
# a scheme then return as-is, otherwise look for a wildcard match and
|
136
|
+
# error if no matches are found.
|
137
|
+
# Else fall back to [target] if no matches are found.
|
138
|
+
def resolve_name(target, ext_glob: false)
|
139
|
+
if (group = group_lookup[target])
|
140
|
+
group.all_targets.to_a
|
141
|
+
elsif @targets.key?(target)
|
142
|
+
[target]
|
143
|
+
elsif (real_target = groups.target_aliases[target])
|
144
|
+
[real_target]
|
145
|
+
elsif GLOB_MATCH_REGEX.match?(target)
|
146
|
+
# URIs and glob wildcards have some overlapping characters. If the target
|
147
|
+
# being resolved parses as a valid target URI and has a scheme defined then
|
148
|
+
# return it as-is and do not try to do further wildcard matching:
|
149
|
+
uri = begin
|
150
|
+
Bolt::Inventory::Target.parse_uri(target)
|
151
|
+
rescue Bolt::ParseError
|
152
|
+
nil
|
153
|
+
end
|
154
|
+
return [target] if uri&.scheme
|
155
|
+
|
156
|
+
targets = []
|
157
|
+
|
158
|
+
# Find groups that match the glob
|
159
|
+
group_lookup.each do |name, grp|
|
160
|
+
next unless match_wildcard?(target, name, ext_glob: ext_glob)
|
161
|
+
targets += grp.all_targets.to_a
|
162
|
+
end
|
163
|
+
|
164
|
+
# Find target names that match the glob
|
165
|
+
targets += groups.all_targets.select { |targ| match_wildcard?(target, targ, ext_glob: ext_glob) }
|
166
|
+
|
167
|
+
# Find target aliases that match the glob
|
168
|
+
targets += groups.target_aliases
|
169
|
+
.select { |tgt_alias, _| match_wildcard?(target, tgt_alias, ext_glob: ext_glob) }
|
170
|
+
.values
|
171
|
+
|
172
|
+
raise(WildcardError, target) if targets.empty?
|
173
|
+
|
174
|
+
targets.uniq
|
175
|
+
else # rubocop:disable Lint/DuplicateBranch
|
176
|
+
[target]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
private :resolve_name
|
180
|
+
|
181
|
+
def expand_targets(targets, ext_glob: false)
|
182
|
+
case targets
|
183
|
+
when Bolt::Target
|
184
|
+
targets
|
185
|
+
when Array
|
186
|
+
targets.map { |tish| expand_targets(tish, ext_glob: ext_glob) }
|
187
|
+
when String
|
188
|
+
# Expand a comma-separated list
|
189
|
+
# Regex magic below is required to workaround `{foo,bar}` glob syntax
|
190
|
+
regex = ext_glob ? EXTENDED_TARGET_REGEX : TARGET_REGEX
|
191
|
+
targets.split(regex).reject(&:empty?).map do |name|
|
192
|
+
ts = resolve_name(name, ext_glob: ext_glob)
|
193
|
+
ts.map do |t|
|
194
|
+
# If the target doesn't exist, evaluate it from the inventory.
|
195
|
+
# Then return a Bolt::Target.
|
196
|
+
unless @targets.key?(t)
|
197
|
+
@targets[t] = create_target_from_inventory(t)
|
198
|
+
end
|
199
|
+
Bolt::Target.new(t, self)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
private :expand_targets
|
205
|
+
|
206
|
+
def remove_target(current_group, target, desired_group)
|
207
|
+
if current_group.name == desired_group
|
208
|
+
current_group.remove_target(target)
|
209
|
+
target.invalidate_group_cache!
|
210
|
+
end
|
211
|
+
current_group.groups.each do |child_group|
|
212
|
+
# If target was in current group, remove it from all child groups
|
213
|
+
if current_group.name == desired_group
|
214
|
+
remove_target(child_group, target, child_group.name)
|
215
|
+
else
|
216
|
+
remove_target(child_group, target, desired_group)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
private :remove_target
|
221
|
+
|
222
|
+
def add_target(current_group, target, desired_group)
|
223
|
+
if current_group.name == desired_group
|
224
|
+
current_group.add_target(target)
|
225
|
+
target.invalidate_group_cache!
|
226
|
+
return true
|
227
|
+
end
|
228
|
+
# Recurse on children Groups if not desired_group
|
229
|
+
current_group.groups.each do |child_group|
|
230
|
+
add_target(child_group, target, desired_group)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
private :add_target
|
234
|
+
|
235
|
+
# Pull in a target definition from the inventory file and evaluate any
|
236
|
+
# associated references. This is used when a target is resolved by
|
237
|
+
# get_targets.
|
238
|
+
def create_target_from_inventory(target_name)
|
239
|
+
target_data = groups.target_collect(target_name) || { 'uri' => target_name }
|
240
|
+
|
241
|
+
target = Bolt::Inventory::Target.new(target_data, self)
|
242
|
+
@targets[target.name] = target
|
243
|
+
|
244
|
+
add_to_group([target], 'all')
|
245
|
+
|
246
|
+
target
|
247
|
+
end
|
248
|
+
|
249
|
+
# Add a brand new target, overriding any existing target with the same
|
250
|
+
# name. This method does not honor target config from the inventory. This
|
251
|
+
# is used when Target.new is called from a plan or with a data hash.
|
252
|
+
def create_target_from_hash(data)
|
253
|
+
# If target already exists, delete old and replace with new, otherwise add to new to all group
|
254
|
+
new_target = Bolt::Inventory::Target.new(data, self)
|
255
|
+
existing_target = @targets.key?(new_target.name)
|
256
|
+
|
257
|
+
validate_target_from_hash(new_target)
|
258
|
+
@targets[new_target.name] = new_target
|
259
|
+
|
260
|
+
if existing_target
|
261
|
+
clear_alia_from_group(groups, new_target.name)
|
262
|
+
else
|
263
|
+
add_to_group([new_target], 'all')
|
264
|
+
end
|
265
|
+
|
266
|
+
if new_target.target_alias
|
267
|
+
groups.insert_alia(new_target.name, Array(new_target.target_alias))
|
268
|
+
end
|
269
|
+
|
270
|
+
new_target
|
271
|
+
end
|
272
|
+
|
273
|
+
def validate_target_from_hash(target)
|
274
|
+
used_groups = Set.new(group_names)
|
275
|
+
used_targets = target_names
|
276
|
+
|
277
|
+
# Make sure there are no group name conflicts
|
278
|
+
if used_groups.include?(target.name)
|
279
|
+
raise ValidationError.new("Target name #{target.name} conflicts with group of the same name", nil)
|
280
|
+
end
|
281
|
+
|
282
|
+
# Validate any aliases
|
283
|
+
if (aliases = target.target_alias)
|
284
|
+
unless aliases.is_a?(Array) || aliases.is_a?(String)
|
285
|
+
msg = "Alias entry on #{t_name} must be a String or Array, not #{aliases.class}"
|
286
|
+
raise ValidationError.new(msg, @name)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# Make sure there are no conflicts with the new target aliases
|
291
|
+
used_aliases = groups.target_aliases
|
292
|
+
Array(target.target_alias).each do |alia|
|
293
|
+
if used_groups.include?(alia)
|
294
|
+
raise ValidationError.new("Alias #{alia} conflicts with group of the same name", nil)
|
295
|
+
elsif used_targets.include?(alia)
|
296
|
+
raise ValidationError.new("Alias #{alia} conflicts with target of the same name", nil)
|
297
|
+
elsif used_aliases[alia] && used_aliases[alia] != target.name
|
298
|
+
raise ValidationError.new(
|
299
|
+
"Alias #{alia} refers to multiple targets: #{used_aliases[alia]} and #{target.name}", nil
|
300
|
+
)
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def clear_alia_from_group(group, target_name)
|
306
|
+
if group.all_target_names.include?(target_name)
|
307
|
+
group.clear_alia(target_name)
|
308
|
+
end
|
309
|
+
group.groups.each do |grp|
|
310
|
+
clear_alia_from_group(grp, target_name)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
def remove_from_group(target, desired_group)
|
315
|
+
unless target.length == 1
|
316
|
+
raise ValidationError.new("'remove_from_group' expects a single Target, got #{target.length}", nil)
|
317
|
+
end
|
318
|
+
|
319
|
+
if desired_group == 'all'
|
320
|
+
raise ValidationError.new("Cannot remove Target from Group 'all'", nil)
|
321
|
+
end
|
322
|
+
|
323
|
+
if group_names.include?(desired_group)
|
324
|
+
remove_target(groups, @targets[target.first.name], desired_group)
|
325
|
+
else
|
326
|
+
raise ValidationError.new("Group #{desired_group} does not exist in inventory", nil)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
def add_to_group(targets, desired_group)
|
331
|
+
if group_names.include?(desired_group)
|
332
|
+
targets.each do |target|
|
333
|
+
# Add the inventory copy of the target
|
334
|
+
add_target(groups, @targets[target.name], desired_group)
|
335
|
+
end
|
336
|
+
else
|
337
|
+
raise ValidationError.new("Group #{desired_group} does not exist in inventory", nil)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
def transport_data_get
|
342
|
+
{ transport: transport, transports: config.transform_values(&:to_h) }
|
343
|
+
end
|
344
|
+
|
345
|
+
def set_var(target, var_hash)
|
346
|
+
@targets[target.name].set_var(var_hash)
|
347
|
+
end
|
348
|
+
|
349
|
+
def vars(target)
|
350
|
+
@targets[target.name].vars
|
351
|
+
end
|
352
|
+
|
353
|
+
def add_facts(target, new_facts = {})
|
354
|
+
@targets[target.name].add_facts(new_facts)
|
355
|
+
target
|
356
|
+
end
|
357
|
+
|
358
|
+
def facts(target)
|
359
|
+
@targets[target.name].facts
|
360
|
+
end
|
361
|
+
|
362
|
+
def set_feature(target, feature, value = true)
|
363
|
+
@targets[target.name].set_feature(feature, value)
|
364
|
+
end
|
365
|
+
|
366
|
+
def features(target)
|
367
|
+
@targets[target.name].features
|
368
|
+
end
|
369
|
+
|
370
|
+
def plugin_hooks(target)
|
371
|
+
@targets[target.name].plugin_hooks
|
372
|
+
end
|
373
|
+
|
374
|
+
def set_config(target, key_or_key_path, value)
|
375
|
+
@targets[target.name].set_config(key_or_key_path, value)
|
376
|
+
end
|
377
|
+
|
378
|
+
def target_config(target)
|
379
|
+
@targets[target.name].config
|
380
|
+
end
|
381
|
+
|
382
|
+
def resources(target)
|
383
|
+
@targets[target.name].resources
|
384
|
+
end
|
385
|
+
|
386
|
+
def resource(target, type, title)
|
387
|
+
@targets[target.name].resource(type, title)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../../bolt/config/options'
|
4
|
+
|
5
|
+
module Bolt
|
6
|
+
class Inventory
|
7
|
+
module Options
|
8
|
+
# Top-level options available in the inventory.
|
9
|
+
OPTIONS = %w[
|
10
|
+
config
|
11
|
+
facts
|
12
|
+
features
|
13
|
+
groups
|
14
|
+
plugin_hooks
|
15
|
+
targets
|
16
|
+
vars
|
17
|
+
version
|
18
|
+
].freeze
|
19
|
+
|
20
|
+
# Definitions used to validate the data.
|
21
|
+
# https://github.com/puppetlabs/bolt/blob/main/schemas/README.md
|
22
|
+
DEFINITIONS = {
|
23
|
+
"alias" => {
|
24
|
+
description: "A unique alias to refer to the target. Aliases cannot conflict "\
|
25
|
+
"with the name of a group, the name of a target, or another alias.",
|
26
|
+
type: [String, Array],
|
27
|
+
uniqueItems: true,
|
28
|
+
items: {
|
29
|
+
type: String,
|
30
|
+
_plugin: true
|
31
|
+
},
|
32
|
+
_plugin: true
|
33
|
+
},
|
34
|
+
"config" => {
|
35
|
+
description: "A map of configuration options.",
|
36
|
+
type: Hash,
|
37
|
+
# These properties are populated as part of Bolt::Inventory.schema
|
38
|
+
properties: {},
|
39
|
+
_plugin: true
|
40
|
+
},
|
41
|
+
"facts" => {
|
42
|
+
description: "A map of system information, also known as facts, for the target.",
|
43
|
+
type: Hash,
|
44
|
+
_plugin: true
|
45
|
+
},
|
46
|
+
"features" => {
|
47
|
+
description: "A list of available features for the target.",
|
48
|
+
type: Array,
|
49
|
+
uniqueItems: true,
|
50
|
+
items: {
|
51
|
+
type: String,
|
52
|
+
_plugin: true
|
53
|
+
},
|
54
|
+
_plugin: true
|
55
|
+
},
|
56
|
+
"groups" => {
|
57
|
+
description: "A list of groups and their associated configuration.",
|
58
|
+
type: Array,
|
59
|
+
items: {
|
60
|
+
type: Hash,
|
61
|
+
required: ["name"],
|
62
|
+
properties: {
|
63
|
+
"config" => { _ref: "config" },
|
64
|
+
"facts" => { _ref: "facts" },
|
65
|
+
"features" => { _ref: "features" },
|
66
|
+
"groups" => { _ref: "groups" },
|
67
|
+
"name" => { _ref: "name" },
|
68
|
+
"plugin_hooks" => { _ref: "plugin_hooks" },
|
69
|
+
"targets" => { _ref: "targets" },
|
70
|
+
"vars" => { _ref: "vars" }
|
71
|
+
},
|
72
|
+
_plugin: true
|
73
|
+
},
|
74
|
+
_plugin: true
|
75
|
+
},
|
76
|
+
"name" => {
|
77
|
+
description: "A human-readable name to refer to the group or target. Names "\
|
78
|
+
"cannot conflict with the name of a group, the name of a target, "\
|
79
|
+
"or the alias of a target. A name is required for a group and is "\
|
80
|
+
"required for a target unless the uri option is set.",
|
81
|
+
type: String,
|
82
|
+
_plugin: true
|
83
|
+
},
|
84
|
+
"plugin_hooks" => {
|
85
|
+
description: "Configuration for the Puppet library plugin used to install the "\
|
86
|
+
"Puppet agent on the target. For more information, see "\
|
87
|
+
"https://pup.pt/bolt-plugin-hooks",
|
88
|
+
type: Hash,
|
89
|
+
properties: {
|
90
|
+
"puppet_library" => {
|
91
|
+
description: "Configuration for the Puppet library plugin.",
|
92
|
+
type: Hash,
|
93
|
+
_plugin: true
|
94
|
+
}
|
95
|
+
},
|
96
|
+
_plugin: true
|
97
|
+
},
|
98
|
+
"targets" => {
|
99
|
+
description: "A list of targets and their associated configuration.",
|
100
|
+
type: Array,
|
101
|
+
items: {
|
102
|
+
type: [String, Hash],
|
103
|
+
properties: {
|
104
|
+
"alias" => { _ref: "alias" },
|
105
|
+
"config" => { _ref: "config" },
|
106
|
+
"facts" => { _ref: "facts" },
|
107
|
+
"features" => { _ref: "features" },
|
108
|
+
"name" => { _ref: "name" },
|
109
|
+
"plugin_hooks" => { _ref: "plugin_hooks" },
|
110
|
+
"uri" => { _ref: "uri" },
|
111
|
+
"vars" => { _ref: "vars" }
|
112
|
+
},
|
113
|
+
_plugin: true
|
114
|
+
},
|
115
|
+
_plugin: true
|
116
|
+
},
|
117
|
+
"uri" => {
|
118
|
+
description: "The URI of the target. This option is required unless the name "\
|
119
|
+
"option is set.",
|
120
|
+
type: String,
|
121
|
+
format: "uri",
|
122
|
+
_plugin: true
|
123
|
+
},
|
124
|
+
"vars" => {
|
125
|
+
description: "A map of variables for the group or target.",
|
126
|
+
type: Hash,
|
127
|
+
_plugin: true
|
128
|
+
},
|
129
|
+
"version" => {
|
130
|
+
description: "The version of the inventory file.",
|
131
|
+
type: Integer,
|
132
|
+
_plugin: false,
|
133
|
+
_example: 2,
|
134
|
+
_default: 2
|
135
|
+
}
|
136
|
+
}.freeze
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|