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,63 @@
|
|
1
|
+
#! /opt/puppetlabs/puppet/bin/ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'puppet'
|
6
|
+
require 'puppet/module_tool/tar'
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
args = JSON.parse($stdin.read)
|
10
|
+
|
11
|
+
Dir.mktmpdir do |puppet_root|
|
12
|
+
# Create temporary directories for all core Puppet settings so we don't clobber
|
13
|
+
# existing state or read from puppet.conf. Also create a temporary modulepath.
|
14
|
+
moduledir = File.join(puppet_root, 'modules')
|
15
|
+
Dir.mkdir(moduledir)
|
16
|
+
cli = Puppet::Settings::REQUIRED_APP_SETTINGS.flat_map do |setting|
|
17
|
+
["--#{setting}", File.join(puppet_root, setting.to_s.chomp('dir'))]
|
18
|
+
end
|
19
|
+
cli << '--modulepath' << moduledir
|
20
|
+
Puppet.initialize_settings(cli)
|
21
|
+
|
22
|
+
Tempfile.open('plugins.tar.gz') do |plugins|
|
23
|
+
File.binwrite(plugins, Base64.decode64(args['plugins']))
|
24
|
+
user = Etc.getpwuid.nil? ? Etc.getlogin : Etc.getpwuid.name
|
25
|
+
Puppet::ModuleTool::Tar.instance.unpack(plugins, moduledir, user)
|
26
|
+
end
|
27
|
+
|
28
|
+
env = Puppet.lookup(:environments).get('production')
|
29
|
+
env.each_plugin_directory do |dir|
|
30
|
+
$LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
31
|
+
end
|
32
|
+
|
33
|
+
if (conn_info = args['_target'])
|
34
|
+
unless (type = conn_info['remote-transport'])
|
35
|
+
puts "Cannot collect facts for a remote target without knowing the remote-transport type."
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
begin
|
40
|
+
require 'puppet/resource_api/transport'
|
41
|
+
rescue LoadError
|
42
|
+
msg = "Could not load 'puppet/resource_api/transport', puppet-resource_api "\
|
43
|
+
"gem version 1.8.0 or greater is required on the proxy target"
|
44
|
+
puts msg
|
45
|
+
exit 1
|
46
|
+
end
|
47
|
+
|
48
|
+
# Transport.connect will modify this hash!
|
49
|
+
transport_conn_info = conn_info.transform_keys(&:to_sym)
|
50
|
+
transport = Puppet::ResourceApi::Transport.connect(type, transport_conn_info)
|
51
|
+
Puppet::ResourceApi::Transport.inject_device(type, transport)
|
52
|
+
|
53
|
+
Puppet[:facts_terminus] = :network_device
|
54
|
+
Puppet[:certname] = conn_info['name']
|
55
|
+
end
|
56
|
+
|
57
|
+
facts = Puppet::Node::Facts.indirection.find(SecureRandom.uuid, environment: env)
|
58
|
+
|
59
|
+
facts.name = facts.values['clientcert']
|
60
|
+
puts(facts.values.to_json)
|
61
|
+
end
|
62
|
+
|
63
|
+
exit 0
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#! /opt/puppetlabs/puppet/bin/ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'puppet'
|
6
|
+
require 'puppet/module_tool/tar'
|
7
|
+
require 'tempfile'
|
8
|
+
|
9
|
+
args = JSON.parse($stdin.read)
|
10
|
+
|
11
|
+
RESOURCE_INSTANCE = /^([^\[]+)\[([^\]]+)\]$/.freeze
|
12
|
+
|
13
|
+
def instance(type_name, resource_name)
|
14
|
+
resource = Puppet::Resource.indirection.find("#{type_name}/#{resource_name}")
|
15
|
+
stringify_resource(resource)
|
16
|
+
end
|
17
|
+
|
18
|
+
Dir.mktmpdir do |puppet_root|
|
19
|
+
# Create temporary directories for all core Puppet settings so we don't clobber
|
20
|
+
# existing state or read from puppet.conf. Also create a temporary modulepath.
|
21
|
+
moduledir = File.join(puppet_root, 'modules')
|
22
|
+
Dir.mkdir(moduledir)
|
23
|
+
cli = Puppet::Settings::REQUIRED_APP_SETTINGS.flat_map do |setting|
|
24
|
+
["--#{setting}", File.join(puppet_root, setting.to_s.chomp('dir'))]
|
25
|
+
end
|
26
|
+
cli << '--modulepath' << moduledir
|
27
|
+
Puppet.initialize_settings(cli)
|
28
|
+
|
29
|
+
Tempfile.open('plugins.tar.gz') do |plugins|
|
30
|
+
File.binwrite(plugins, Base64.decode64(args['plugins']))
|
31
|
+
user = Etc.getpwuid.nil? ? Etc.getlogin : Etc.getpwuid.name
|
32
|
+
Puppet::ModuleTool::Tar.instance.unpack(plugins, moduledir, user)
|
33
|
+
end
|
34
|
+
|
35
|
+
env = Puppet.lookup(:environments).get('production')
|
36
|
+
env.each_plugin_directory do |dir|
|
37
|
+
$LOAD_PATH << dir unless $LOAD_PATH.include?(dir)
|
38
|
+
end
|
39
|
+
|
40
|
+
if (conn_info = args['_target'])
|
41
|
+
unless (type = conn_info['remote-transport'])
|
42
|
+
puts "Cannot discover resources for a remote target without knowing it's the remote-transport type."
|
43
|
+
exit 1
|
44
|
+
end
|
45
|
+
|
46
|
+
begin
|
47
|
+
require 'puppet/resource_api/transport'
|
48
|
+
rescue LoadError
|
49
|
+
msg = "Could not load 'puppet/resource_api/transport', puppet-resource_api "\
|
50
|
+
"gem version 1.8.0 or greater is required on the proxy target"
|
51
|
+
puts msg
|
52
|
+
exit 1
|
53
|
+
end
|
54
|
+
|
55
|
+
# Transport.connect will modify this hash!
|
56
|
+
transport_conn_info = conn_info.transform_keys(&:to_sym)
|
57
|
+
|
58
|
+
transport = Puppet::ResourceApi::Transport.connect(type, transport_conn_info)
|
59
|
+
Puppet::ResourceApi::Transport.inject_device(type, transport)
|
60
|
+
|
61
|
+
Puppet[:facts_terminus] = :network_device
|
62
|
+
Puppet[:certname] = conn_info['name']
|
63
|
+
end
|
64
|
+
|
65
|
+
resources = args['resources'].flat_map do |resource_desc|
|
66
|
+
if (match = RESOURCE_INSTANCE.match(resource_desc))
|
67
|
+
Puppet::Resource.indirection.find("#{match[1]}/#{match[2]}", environment: env)
|
68
|
+
else
|
69
|
+
Puppet::Resource.indirection.search(resource_desc, environment: env)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
puts({ 'resources' => resources }.to_json)
|
73
|
+
end
|
74
|
+
|
75
|
+
exit 0
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Aggregates the key/value pairs in the results of a ResultSet into a hash
|
4
|
+
# mapping the keys to a hash of each distinct value and how many targets returned
|
5
|
+
# that value for the key.
|
6
|
+
Puppet::Functions.create_function(:'aggregate::count') do
|
7
|
+
dispatch :aggregate_count do
|
8
|
+
param 'ResultSet', :resultset
|
9
|
+
end
|
10
|
+
|
11
|
+
def aggregate_count(resultset)
|
12
|
+
resultset.each_with_object({}) do |result, agg|
|
13
|
+
result.value.each do |key, val|
|
14
|
+
agg[key] ||= {}
|
15
|
+
agg[key][val.to_s] ||= 0
|
16
|
+
agg[key][val.to_s] += 1
|
17
|
+
end
|
18
|
+
agg
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Aggregates the key/value pairs in the results of a ResultSet into a hash
|
4
|
+
# mapping the keys to a hash of each distinct value and the list of nodes
|
5
|
+
# returning that value for the key.
|
6
|
+
Puppet::Functions.create_function(:'aggregate::nodes') do
|
7
|
+
dispatch :aggregate_nodes do
|
8
|
+
param 'ResultSet', :resultset
|
9
|
+
end
|
10
|
+
|
11
|
+
def aggregate_nodes(resultset)
|
12
|
+
resultset.each_with_object({}) do |result, agg|
|
13
|
+
result.value.each do |key, val|
|
14
|
+
agg[key] ||= {}
|
15
|
+
agg[key][val.to_s] ||= []
|
16
|
+
agg[key][val.to_s] << result.target.name
|
17
|
+
end
|
18
|
+
agg
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Aggregates the key/value pairs in the results of a ResultSet into a hash
|
4
|
+
# mapping the keys to a hash of each distinct value and the list of targets
|
5
|
+
# returning that value for the key.
|
6
|
+
Puppet::Functions.create_function(:'aggregate::targets') do
|
7
|
+
dispatch :aggregate_targets do
|
8
|
+
param 'ResultSet', :resultset
|
9
|
+
end
|
10
|
+
|
11
|
+
def aggregate_targets(resultset)
|
12
|
+
resultset.each_with_object({}) do |result, agg|
|
13
|
+
result.value.each do |key, val|
|
14
|
+
agg[key] ||= {}
|
15
|
+
agg[key][val.to_s] ||= []
|
16
|
+
agg[key][val.to_s] << result.target.name
|
17
|
+
end
|
18
|
+
agg
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# @summary
|
2
|
+
# Run a task, command, or script on targets and aggregate the results as
|
3
|
+
# a count of targets for each value of a key.
|
4
|
+
#
|
5
|
+
# This plan accepts an action and a list of targets. The action can be the name
|
6
|
+
# of a task, a script, or a command to run. It will run the action on the
|
7
|
+
# targets and aggregate the key/value pairs in each Result into a hash, mapping
|
8
|
+
# the keys to a hash of each distinct value and how many targets returned that
|
9
|
+
# value for the key.
|
10
|
+
#
|
11
|
+
# @param command
|
12
|
+
# The command to run. Mutually exclusive with script and task.
|
13
|
+
# @param script
|
14
|
+
# The path to the script to run. Mutually exclusive with command and task.
|
15
|
+
# @param task
|
16
|
+
# The name of the task to run. Mutually exclusive with command and script.
|
17
|
+
# @param targets
|
18
|
+
# The list of targets to run the action on.
|
19
|
+
# @param params
|
20
|
+
# A hash of parameters and options to pass to the `run_*` function
|
21
|
+
# associated with the action (e.g. run_task).
|
22
|
+
plan aggregate::count(
|
23
|
+
Optional[String[0]] $task = undef,
|
24
|
+
Optional[String[0]] $command = undef,
|
25
|
+
Optional[String[0]] $script = undef,
|
26
|
+
TargetSpec $targets,
|
27
|
+
Hash[String, Data] $params = {}
|
28
|
+
) {
|
29
|
+
|
30
|
+
# Validation
|
31
|
+
$type_count = [$task, $command, $script].reduce(0) |$acc, $v| {
|
32
|
+
if ($v) {
|
33
|
+
$acc + 1
|
34
|
+
} else {
|
35
|
+
$acc
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
if ($type_count == 0) {
|
40
|
+
fail_plan("Must specify a command, script, or task to run", 'aggregate/invalid-params')
|
41
|
+
}
|
42
|
+
|
43
|
+
if ($type_count > 1) {
|
44
|
+
fail_plan("Must specify only one command, script, or task to run", 'aggregate/invalid-params')
|
45
|
+
}
|
46
|
+
|
47
|
+
$res = if ($task) {
|
48
|
+
run_task($task, $targets, $params)
|
49
|
+
} elsif ($command) {
|
50
|
+
run_command($command, $targets, $params)
|
51
|
+
} elsif ($script) {
|
52
|
+
run_script($script, $targets, $params)
|
53
|
+
}
|
54
|
+
|
55
|
+
return aggregate::count($res)
|
56
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# @summary
|
2
|
+
# Run a task, command, or script on targets and aggregate the results as
|
3
|
+
# the list of targets for each value of a key in the results.
|
4
|
+
#
|
5
|
+
# This plan accepts an action and a list of targets. The action can be the name
|
6
|
+
# of a task, a script, or a command to run. It will run the action on the
|
7
|
+
# targets and aggregate the key/value pairs in each Result into a hash, mapping
|
8
|
+
# the keys to a hash of each distinct value and a list of targets returning that
|
9
|
+
# value.
|
10
|
+
#
|
11
|
+
# @param command
|
12
|
+
# The command to run. Mutually exclusive with script and task.
|
13
|
+
# @param script
|
14
|
+
# The path to the script to run. Mutually exclusive with command and task.
|
15
|
+
# @param task
|
16
|
+
# The name of the task to run. Mutually exclusive with command and script.
|
17
|
+
# @param targets
|
18
|
+
# The list of targets to run the action on.
|
19
|
+
# @param params
|
20
|
+
# A hash of parameters and options to pass to the `run_*` function
|
21
|
+
# associated with the action (e.g. run_task).
|
22
|
+
plan aggregate::targets(
|
23
|
+
Optional[String[0]] $task = undef,
|
24
|
+
Optional[String[0]] $command = undef,
|
25
|
+
Optional[String[0]] $script = undef,
|
26
|
+
TargetSpec $targets,
|
27
|
+
Hash[String, Data] $params = {}
|
28
|
+
) {
|
29
|
+
|
30
|
+
# Validation
|
31
|
+
$type_count = [$task, $command, $script].reduce(0) |$acc, $v| {
|
32
|
+
if ($v) {
|
33
|
+
$acc + 1
|
34
|
+
} else {
|
35
|
+
$acc
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
if ($type_count == 0) {
|
40
|
+
fail_plan("Must specify a command, script, or task to run", 'aggregate/invalid-params')
|
41
|
+
}
|
42
|
+
|
43
|
+
if ($type_count > 1) {
|
44
|
+
fail_plan("Must specify only one command, script, or task to run", 'aggregate/invalid-params')
|
45
|
+
}
|
46
|
+
|
47
|
+
$res = if ($task) {
|
48
|
+
run_task($task, $targets, $params)
|
49
|
+
} elsif ($command) {
|
50
|
+
run_command($command, $targets, $params)
|
51
|
+
} elsif ($script) {
|
52
|
+
run_script($script, $targets, $params)
|
53
|
+
}
|
54
|
+
|
55
|
+
return aggregate::targets($res)
|
56
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Merges two ResultSets into a new ResultSet
|
4
|
+
Puppet::Functions.create_function(:'canary::merge') do
|
5
|
+
dispatch :merge_results do
|
6
|
+
param 'ResultSet', :merger
|
7
|
+
param 'ResultSet', :mergee
|
8
|
+
end
|
9
|
+
|
10
|
+
def merge_results(merger, mergee)
|
11
|
+
Bolt::ResultSet.new(merger.results + mergee.results)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Splits an array into two groups, where the 1st group is a randomly selected
|
4
|
+
# sample of the input (of the specified size) and the 2nd group is the remainder.
|
5
|
+
#
|
6
|
+
# This function takes 2 parameters:
|
7
|
+
# * The array to split (Array)
|
8
|
+
# * The number of items to sample from the array (Integer)
|
9
|
+
#
|
10
|
+
# Returns an array of [<sample>, <remainder>].
|
11
|
+
Puppet::Functions.create_function(:'canary::random_split') do
|
12
|
+
dispatch :rand do
|
13
|
+
param 'Array', :arr
|
14
|
+
param 'Integer', :size
|
15
|
+
end
|
16
|
+
|
17
|
+
def rand(arr, size)
|
18
|
+
canaries = arr.sample(size)
|
19
|
+
rest = arr.reject { |r| canaries.include?(r) }
|
20
|
+
[canaries, rest]
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Returns a ResultSet with canary/skipped-target errors for each Target provided.
|
4
|
+
#
|
5
|
+
# This function takes a single parameter:
|
6
|
+
# * List of targets (Array[Variant[Target,String]])
|
7
|
+
#
|
8
|
+
# Returns a ResultSet.
|
9
|
+
Puppet::Functions.create_function(:'canary::skip') do
|
10
|
+
dispatch :skip_result do
|
11
|
+
param 'Array[Variant[Target,String]]', :targets
|
12
|
+
end
|
13
|
+
|
14
|
+
def skip_result(targets)
|
15
|
+
results = targets.map do |target|
|
16
|
+
target = Bolt::Target.new(target) unless target.is_a? Bolt::Target
|
17
|
+
Bolt::Result.new(target, value: { '_error' => {
|
18
|
+
'msg' => "Skipped #{target.name} because of a previous failure",
|
19
|
+
'kind' => 'canary/skipped-target',
|
20
|
+
'details' => {}
|
21
|
+
} })
|
22
|
+
end
|
23
|
+
Bolt::ResultSet.new(results)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# @summary
|
2
|
+
# Run a task, command or script on canary targets before running it on all targets.
|
3
|
+
#
|
4
|
+
# This plan accepts a action and a $targets parameter. The action can be the name
|
5
|
+
# of a task, a script or a command to run. It will run the action on a canary
|
6
|
+
# group of targets and only continue to the rest of the targets if it succeeds on
|
7
|
+
# all canaries. This returns a ResultSet object with a Result for every target.
|
8
|
+
# Any skipped targets will have a 'canary/skipped-target' error kind.
|
9
|
+
#
|
10
|
+
# @param task
|
11
|
+
# The name of the task to run. Mutually exclusive with command and script.
|
12
|
+
# @param command
|
13
|
+
# The command to run. Mutually exclusive with task and script.
|
14
|
+
# @param script
|
15
|
+
# The script to run. Mutually exclusive with task and command.
|
16
|
+
# @param targets
|
17
|
+
# The target to run on.
|
18
|
+
# @param params
|
19
|
+
# The parameters to use for the task.
|
20
|
+
# @param canary_size
|
21
|
+
# How many targets to use in the canary group.
|
22
|
+
#
|
23
|
+
# @return ResultSet a merged resultset from running the action on all targets
|
24
|
+
#
|
25
|
+
# @example Run a command
|
26
|
+
# run_plan(canary, command => 'whoami', targets => $mytargets)
|
27
|
+
#
|
28
|
+
plan canary(
|
29
|
+
Optional[String[0]] $task = undef,
|
30
|
+
Optional[String[0]] $command = undef,
|
31
|
+
Optional[String[0]] $script = undef,
|
32
|
+
TargetSpec $targets,
|
33
|
+
Hash[String, Data] $params = {},
|
34
|
+
Integer $canary_size = 1
|
35
|
+
) {
|
36
|
+
|
37
|
+
# Validation
|
38
|
+
$type_count = [$task, $command, $script].reduce(0) |$acc, $v| {
|
39
|
+
if ($v) {
|
40
|
+
$acc + 1
|
41
|
+
} else {
|
42
|
+
$acc
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
if ($type_count == 0) {
|
47
|
+
fail_plan("Must specify a command, script, or task to run", 'canary/invalid-params')
|
48
|
+
}
|
49
|
+
|
50
|
+
if ($type_count > 1) {
|
51
|
+
fail_plan("Must specify only one command, script, or task to run", 'canary/invalid-params')
|
52
|
+
}
|
53
|
+
|
54
|
+
[$canaries, $rest] = canary::random_split(get_targets($targets), $canary_size)
|
55
|
+
$catch_params = $params + { '_catch_errors' => true }
|
56
|
+
|
57
|
+
if ($task) {
|
58
|
+
$action = 'run_task'
|
59
|
+
$object = $task
|
60
|
+
$canr = run_task($task, $canaries, $catch_params)
|
61
|
+
if ($canr.ok) {
|
62
|
+
$restr = run_task($task, $rest, $catch_params)
|
63
|
+
}
|
64
|
+
} elsif ($command) {
|
65
|
+
$action = 'run_command'
|
66
|
+
$object = $command
|
67
|
+
$canr = run_command($command, $canaries, $catch_params)
|
68
|
+
if ($canr.ok) {
|
69
|
+
$restr = run_command($command, $rest, $catch_params)
|
70
|
+
}
|
71
|
+
} elsif ($script) {
|
72
|
+
$action = 'run_script'
|
73
|
+
$object = $script
|
74
|
+
$canr = run_script($script, $canaries, $catch_params)
|
75
|
+
if ($canr.ok) {
|
76
|
+
$restr = run_script($script, $rest, $catch_params)
|
77
|
+
}
|
78
|
+
}
|
79
|
+
|
80
|
+
unless ($canr.ok) {
|
81
|
+
$restr = canary::skip($rest)
|
82
|
+
}
|
83
|
+
|
84
|
+
$merged_result = canary::merge($canr, $restr)
|
85
|
+
|
86
|
+
unless ($merged_result.ok) {
|
87
|
+
if ($canr.ok) {
|
88
|
+
$message = "Plan failed for ${merged_result.error_set.count} targets."
|
89
|
+
}
|
90
|
+
else {
|
91
|
+
$message = "${canr.error_set.count} canary target failures. ${restr.count} targets skipped."
|
92
|
+
}
|
93
|
+
$details = {'action' => $action,
|
94
|
+
'object' => $object,
|
95
|
+
'result_set' => $merged_result}
|
96
|
+
fail_plan($message, 'bolt/run-failure', $details)
|
97
|
+
}
|
98
|
+
|
99
|
+
return $merged_result
|
100
|
+
}
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# @summary
|
2
|
+
# Tests that the provided Puppet Connect input data is complete, meaning that all consuming inventory targets are connectable.
|
3
|
+
# You should run this plan with the following command:
|
4
|
+
# PUPPET_CONNECT_INPUT_DATA=/path/to/input_data.yaml bolt plan run puppet_connect::test_input_data
|
5
|
+
# where /path/to/input_data.yaml is the path to the input_data.yaml file containing the key-value input for the
|
6
|
+
# puppet_connect_data plugin. If the plan fails on some targets, then you can use Bolt's --rerun option to rerun the plan on
|
7
|
+
# just the failed targets:
|
8
|
+
# PUPPET_CONNECT_INPUT_DATA=/path/to/input_data.yaml bolt plan run puppet_connect::test_input_data --rerun failure
|
9
|
+
# Note that this plan should only be used as part of the copy-pastable "test input data" workflow specified in the Puppet
|
10
|
+
# Connect docs.
|
11
|
+
#
|
12
|
+
# @param targets
|
13
|
+
# The set of targets to test. Usually this should be 'all', the default.
|
14
|
+
#
|
15
|
+
# @return ResultSet the result of invoking the 'is connectable?' query on all
|
16
|
+
# the targets. Note that this query currently consists of running the 'echo'
|
17
|
+
# command.
|
18
|
+
#
|
19
|
+
plan puppet_connect::test_input_data(TargetSpec $targets = 'all') {
|
20
|
+
$targs = get_targets($targets)
|
21
|
+
$unique_plugins = $targs.group_by |$t| {$t.plugin_hooks['puppet_library']}
|
22
|
+
if ($unique_plugins.keys.length > 1) {
|
23
|
+
out::message('Multiple puppet_library plugin hooks detected')
|
24
|
+
$unique_plugins.each |$plug, $target_list| {
|
25
|
+
$target_message = if ($target_list.length > 10) {
|
26
|
+
"${target_list.length} targets"
|
27
|
+
} else {
|
28
|
+
$target_list.join(', ')
|
29
|
+
}
|
30
|
+
out::message("Plugin hook ${plug} configured for ${target_message}")
|
31
|
+
}
|
32
|
+
fail_plan("The puppet_library plugin config must be the same across all targets")
|
33
|
+
}
|
34
|
+
$targs.each |$target| {
|
35
|
+
case $target.transport {
|
36
|
+
'ssh': {
|
37
|
+
$private_key_config = dig($target.config, 'ssh', 'private-key')
|
38
|
+
if $private_key_config =~ String {
|
39
|
+
$msg = @("END")
|
40
|
+
The SSH private key of the ${$target} target points to a filepath on disk,
|
41
|
+
which is not allowed in Puppet Connect. Instead, the private key contents must
|
42
|
+
be specified and this should be done via the PuppetConnectData plugin. Below is
|
43
|
+
an example of a Puppet Connect-compatible specification of the private-key. First,
|
44
|
+
we start with the inventory file:
|
45
|
+
...
|
46
|
+
private-key:
|
47
|
+
_plugin: puppet_connect_data
|
48
|
+
key: ssh_private_key
|
49
|
+
...
|
50
|
+
|
51
|
+
Next is the corresponding entry in the input data file:
|
52
|
+
...
|
53
|
+
ssh_private_key:
|
54
|
+
key-data:
|
55
|
+
<private_key_contents>
|
56
|
+
...
|
57
|
+
| END
|
58
|
+
|
59
|
+
out::message($msg)
|
60
|
+
fail_plan("The SSH private key of the ${$target} target points to a filepath on disk")
|
61
|
+
}
|
62
|
+
|
63
|
+
# Disable SSH autoloading to prevent false positive results
|
64
|
+
# (input data is wrong but target is still connectable due
|
65
|
+
# to autoloaded config)
|
66
|
+
set_config($target, ['ssh', 'load-config'], false)
|
67
|
+
# Maintain configuration parity with Puppet Connect to improve
|
68
|
+
# the reliability of our test
|
69
|
+
set_config($target, ['ssh', 'host-key-check'], false)
|
70
|
+
}
|
71
|
+
'winrm': {
|
72
|
+
# Maintain configuration parity with Puppet Connect
|
73
|
+
set_config($target, ['winrm', 'ssl'], false)
|
74
|
+
set_config($target, ['winrm', 'ssl-verify'], false)
|
75
|
+
}
|
76
|
+
default: {
|
77
|
+
fail_plan("Inventory contains target ${target} with unsupported transport, must be ssh or winrm")
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
# Bolt defaults to using the "module" based form of the puppet_agent plugin. Connect defaults
|
82
|
+
# to using the "task" based form as *only* the task based form in supported in Connect. This check
|
83
|
+
# ensures that if the default is not being used, only task based plugins are allowed.
|
84
|
+
$plugin = $target.plugin_hooks["puppet_library"]
|
85
|
+
$user_configured_plugin = $plugin != { "plugin"=> "puppet_agent", "stop_service"=> true }
|
86
|
+
if ($user_configured_plugin and $plugin["plugin"] != "task"){
|
87
|
+
fail_plan("Only task plugins are acceptable for puppet_library hook")
|
88
|
+
}
|
89
|
+
}
|
90
|
+
# The SSH/WinRM transports will report an 'unknown host' error for targets where
|
91
|
+
# 'host' is unknown so run_command's implementation will take care of raising that
|
92
|
+
# error for us.
|
93
|
+
return run_command('echo Connected', $targs)
|
94
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# @summary
|
2
|
+
# Collect facts for the specified targets from PuppetDB and store them
|
3
|
+
# on the Targets.
|
4
|
+
#
|
5
|
+
# This plan accepts a list of targets to collect facts for from the configured
|
6
|
+
# PuppetDB connection. After collecting facts, they are stored on each target's
|
7
|
+
# Target object. The updated facts can then be accessed using `$target.facts`.
|
8
|
+
#
|
9
|
+
# @param targets
|
10
|
+
# The targets to collect facts for.
|
11
|
+
plan puppetdb_fact(TargetSpec $targets) {
|
12
|
+
$targs = get_targets($targets)
|
13
|
+
$certnames = $targs.map |$target| { $target.host }
|
14
|
+
$pdb_facts = puppetdb_fact($certnames)
|
15
|
+
$targs.each |$target| {
|
16
|
+
add_facts($target, $pdb_facts[$target.host])
|
17
|
+
}
|
18
|
+
|
19
|
+
return $pdb_facts
|
20
|
+
}
|