bolt 3.22.1 → 3.24.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of bolt might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Puppetfile +9 -9
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_command.rb +32 -1
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +20 -1
- data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +23 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +28 -23
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +22 -19
- data/lib/bolt/application.rb +17 -10
- data/lib/bolt/applicator.rb +8 -2
- data/lib/bolt/bolt_option_parser.rb +4 -1
- data/lib/bolt/catalog.rb +1 -1
- data/lib/bolt/config/options.rb +65 -49
- data/lib/bolt/config/transport/local.rb +1 -0
- data/lib/bolt/config/transport/lxd.rb +9 -0
- data/lib/bolt/config.rb +12 -3
- data/lib/bolt/inventory/inventory.rb +30 -11
- data/lib/bolt/outputter/human.rb +10 -4
- data/lib/bolt/outputter/json.rb +3 -1
- data/lib/bolt/outputter/rainbow.rb +2 -1
- data/lib/bolt/pal/yaml_plan/loader.rb +1 -1
- data/lib/bolt/pal.rb +6 -2
- data/lib/bolt/plugin/puppetdb.rb +8 -5
- data/lib/bolt/plugin.rb +2 -1
- data/lib/bolt/puppetdb/client.rb +90 -129
- data/lib/bolt/puppetdb/config.rb +21 -8
- data/lib/bolt/puppetdb/instance.rb +146 -0
- data/lib/bolt/result.rb +1 -1
- data/lib/bolt/transport/orch/connection.rb +2 -1
- data/lib/bolt/transport/winrm/connection.rb +18 -11
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/file_cache.rb +10 -8
- data/lib/bolt_spec/plans/action_stubs/download_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/plan_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/task_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs.rb +2 -2
- data/lib/bolt_spec/plans/mock_executor.rb +1 -1
- data/lib/bolt_spec/plans.rb +11 -1
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ad3bbc9413aac278feeac8a7e31173bd065f0029fb211d7e1906c4803a4c390
|
4
|
+
data.tar.gz: 387d3a07844139eb29a1db06d1792acfdad6a09eab2b5576a9c4d34fdffdaca8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83c1685fc238f049dad5cf841ea55f37c57a1aa59d66ef420d754b78d7b0ba8cca4533accb2cfbe53915587f1832beb7cbf956501486de63e135933b57f5fa98
|
7
|
+
data.tar.gz: c6900fde1fd9234a603171c79c2f2b3a22b2d2661797b94bf0afd2050f4ef5cc32844562734d3e41bd94464806e1efaabaac346d6887773f547c801c33cc3d6f
|
data/Puppetfile
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
forge
|
3
|
+
forge 'https://forge.puppetlabs.com'
|
4
4
|
|
5
5
|
moduledir File.join(File.dirname(__FILE__), 'modules')
|
6
6
|
|
7
7
|
# Core modules used by 'apply'
|
8
|
-
mod 'puppetlabs-service', '2.
|
9
|
-
mod 'puppetlabs-puppet_agent', '4.
|
8
|
+
mod 'puppetlabs-service', '2.2.0'
|
9
|
+
mod 'puppetlabs-puppet_agent', '4.11.0'
|
10
10
|
mod 'puppetlabs-facts', '1.4.0'
|
11
11
|
|
12
12
|
# Core types and providers for Puppet 6
|
13
13
|
mod 'puppetlabs-augeas_core', '1.2.0'
|
14
14
|
mod 'puppetlabs-host_core', '1.1.0'
|
15
|
-
mod 'puppetlabs-scheduled_task', '3.0
|
15
|
+
mod 'puppetlabs-scheduled_task', '3.1.0'
|
16
16
|
mod 'puppetlabs-sshkeys_core', '2.3.0'
|
17
17
|
mod 'puppetlabs-zfs_core', '1.3.0'
|
18
18
|
mod 'puppetlabs-cron_core', '1.1.0'
|
@@ -22,14 +22,14 @@ mod 'puppetlabs-yumrepo_core', '1.1.0'
|
|
22
22
|
mod 'puppetlabs-zone_core', '1.0.3'
|
23
23
|
|
24
24
|
# Useful additional modules
|
25
|
-
mod 'puppetlabs-package', '2.
|
25
|
+
mod 'puppetlabs-package', '2.2.0'
|
26
26
|
mod 'puppetlabs-powershell_task_helper', '0.1.0'
|
27
|
-
mod 'puppetlabs-puppet_conf', '1.
|
27
|
+
mod 'puppetlabs-puppet_conf', '1.3.0'
|
28
28
|
mod 'puppetlabs-python_task_helper', '0.5.0'
|
29
|
-
mod 'puppetlabs-reboot', '4.
|
30
|
-
mod 'puppetlabs-ruby_task_helper', '0.6.
|
29
|
+
mod 'puppetlabs-reboot', '4.2.0'
|
30
|
+
mod 'puppetlabs-ruby_task_helper', '0.6.1'
|
31
31
|
mod 'puppetlabs-ruby_plugin_helper', '0.2.0'
|
32
|
-
mod 'puppetlabs-stdlib', '8.
|
32
|
+
mod 'puppetlabs-stdlib', '8.2.0'
|
33
33
|
|
34
34
|
# Plugin modules
|
35
35
|
mod 'puppetlabs-aws_inventory', '0.7.0'
|
@@ -17,6 +17,8 @@ require 'bolt/error'
|
|
17
17
|
# > **Note:** Not available in apply block
|
18
18
|
#
|
19
19
|
Puppet::Functions.create_function(:puppetdb_command) do
|
20
|
+
# Send a command with a payload to PuppetDB.
|
21
|
+
#
|
20
22
|
# @param command The command to invoke.
|
21
23
|
# @param version The version of the command to invoke.
|
22
24
|
# @param payload The payload to the command.
|
@@ -38,7 +40,36 @@ Puppet::Functions.create_function(:puppetdb_command) do
|
|
38
40
|
return_type 'String'
|
39
41
|
end
|
40
42
|
|
43
|
+
# Send a command with a payload to a named PuppetDB instance.
|
44
|
+
#
|
45
|
+
# @param command The command to invoke.
|
46
|
+
# @param version The version of the command to invoke.
|
47
|
+
# @param payload The payload to the command.
|
48
|
+
# @param instance The PuppetDB instance to send the command to.
|
49
|
+
# @return The UUID identifying the response sent by PuppetDB.
|
50
|
+
# @example Replace facts for a target using a named PuppetDB instance
|
51
|
+
# $payload = {
|
52
|
+
# 'certname' => 'localhost',
|
53
|
+
# 'environment' => 'dev',
|
54
|
+
# 'producer' => 'bolt',
|
55
|
+
# 'producer_timestamp' => '1970-01-01',
|
56
|
+
# 'values' => { 'orchestrator' => 'bolt' }
|
57
|
+
# }
|
58
|
+
#
|
59
|
+
# puppetdb_command('replace_facts', 5, $payload, 'instance-1')
|
60
|
+
dispatch :puppetdb_command_with_instance do
|
61
|
+
param 'String[1]', :command
|
62
|
+
param 'Integer', :version
|
63
|
+
param 'Hash[Data, Data]', :payload
|
64
|
+
param 'String', :instance
|
65
|
+
return_type 'String'
|
66
|
+
end
|
67
|
+
|
41
68
|
def puppetdb_command(command, version, payload)
|
69
|
+
puppetdb_command_with_instance(command, version, payload, nil)
|
70
|
+
end
|
71
|
+
|
72
|
+
def puppetdb_command_with_instance(command, version, payload, instance)
|
42
73
|
# Disallow in apply blocks.
|
43
74
|
unless Puppet[:tasks]
|
44
75
|
raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
|
@@ -61,6 +92,6 @@ Puppet::Functions.create_function(:puppetdb_command) do
|
|
61
92
|
)
|
62
93
|
end
|
63
94
|
|
64
|
-
puppetdb_client.send_command(command, version, payload)
|
95
|
+
puppetdb_client.send_command(command, version, payload, instance)
|
65
96
|
end
|
66
97
|
end
|
@@ -7,6 +7,8 @@ require 'bolt/error'
|
|
7
7
|
# If a node is not found in PuppetDB, it's included in the returned hash with an empty facts hash.
|
8
8
|
# Otherwise, the node is included in the hash with a value that is a hash of its facts.
|
9
9
|
Puppet::Functions.create_function(:puppetdb_fact) do
|
10
|
+
# Collect facts from PuppetDB.
|
11
|
+
#
|
10
12
|
# @param certnames Array of certnames.
|
11
13
|
# @return A hash of certname to facts hash for each matched Target.
|
12
14
|
# @example Get facts for nodes
|
@@ -16,13 +18,30 @@ Puppet::Functions.create_function(:puppetdb_fact) do
|
|
16
18
|
return_type 'Hash[String, Data]'
|
17
19
|
end
|
18
20
|
|
21
|
+
# Collects facts from a named PuppetDB instance.
|
22
|
+
#
|
23
|
+
# @param certnames Array of certnames.
|
24
|
+
# @param instance The PuppetDB instance to query.
|
25
|
+
# @return A hash of certname to facts hash for each matched Target.
|
26
|
+
# @example Get facts for nodes from a named PuppetDB instance
|
27
|
+
# puppetdb_fact(['app.example.com', 'db.example.com'], 'instance-1')
|
28
|
+
dispatch :puppetdb_fact_with_instance do
|
29
|
+
param 'Array[String]', :certnames
|
30
|
+
param 'String', :instance
|
31
|
+
return_type 'Hash[String, Data]'
|
32
|
+
end
|
33
|
+
|
19
34
|
def puppetdb_fact(certnames)
|
35
|
+
puppetdb_fact_with_instance(certnames, nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
def puppetdb_fact_with_instance(certnames, instance)
|
20
39
|
puppetdb_client = Puppet.lookup(:bolt_pdb_client)
|
21
40
|
# Bolt executor not expected when invoked from apply block
|
22
41
|
executor = Puppet.lookup(:bolt_executor) { nil }
|
23
42
|
# Send Analytics Report
|
24
43
|
executor&.report_function_call(self.class.name)
|
25
44
|
|
26
|
-
puppetdb_client.facts_for_node(certnames)
|
45
|
+
puppetdb_client.facts_for_node(certnames, instance)
|
27
46
|
end
|
28
47
|
end
|
@@ -6,6 +6,8 @@ require 'bolt/error'
|
|
6
6
|
# using Bolt's PuppetDB client.
|
7
7
|
Puppet::Functions.create_function(:puppetdb_query) do
|
8
8
|
# rubocop:disable Layout/LineLength
|
9
|
+
# Make a query to PuppetDB.
|
10
|
+
#
|
9
11
|
# @param query A PQL query.
|
10
12
|
# Learn more about [Puppet's query language](https://puppet.com/docs/puppetdb/latest/api/query/tutorial-pql.html), PQL.
|
11
13
|
# @return Results of the PuppetDB query.
|
@@ -16,15 +18,35 @@ Puppet::Functions.create_function(:puppetdb_query) do
|
|
16
18
|
param 'Variant[String, Array[Data]]', :query
|
17
19
|
return_type 'Array[Data]'
|
18
20
|
end
|
21
|
+
|
22
|
+
# rubocop:disable Layout/LineLength
|
23
|
+
# Make a query to a named PuppetDB instance.
|
24
|
+
#
|
25
|
+
# @param query A PQL query.
|
26
|
+
# Learn more about [Puppet's query language](https://puppet.com/docs/puppetdb/latest/api/query/tutorial-pql.html), PQL.
|
27
|
+
# @param instance The PuppetDB instance to query.
|
28
|
+
# @return Results of the PuppetDB query.
|
29
|
+
# @example Request certnames for all nodes using a named PuppetDB instance
|
30
|
+
# puppetdb_query('nodes[certname] {}', 'instance-1')
|
31
|
+
# rubocop:enable Layout/LineLength
|
32
|
+
dispatch :make_query_with_instance do
|
33
|
+
param 'Variant[String, Array[Data]]', :query
|
34
|
+
param 'String', :instance
|
35
|
+
return_type 'Array[Data]'
|
36
|
+
end
|
19
37
|
# The query type could be more specific ASTQuery = Array[Variant[String, ASTQuery]]
|
20
38
|
|
21
39
|
def make_query(query)
|
40
|
+
make_query_with_instance(query, nil)
|
41
|
+
end
|
42
|
+
|
43
|
+
def make_query_with_instance(query, instance)
|
22
44
|
puppetdb_client = Puppet.lookup(:bolt_pdb_client)
|
23
45
|
# Bolt executor not expected when invoked from apply block
|
24
46
|
executor = Puppet.lookup(:bolt_executor) { nil }
|
25
47
|
# Send Analytics Report
|
26
48
|
executor&.report_function_call(self.class.name)
|
27
49
|
|
28
|
-
puppetdb_client.make_query(query)
|
50
|
+
puppetdb_client.make_query(query, nil, instance)
|
29
51
|
end
|
30
52
|
end
|
@@ -57,6 +57,7 @@ Puppet::Functions.create_function(:run_task) do
|
|
57
57
|
|
58
58
|
options, params = args.partition { |k, _v| k.start_with?('_') }.map(&:to_h)
|
59
59
|
options = options.transform_keys { |k| k.sub(/^_/, '').to_sym }
|
60
|
+
options[:description] = description if description
|
60
61
|
|
61
62
|
executor = Puppet.lookup(:bolt_executor)
|
62
63
|
inventory = Puppet.lookup(:bolt_inventory)
|
@@ -68,18 +69,24 @@ Puppet::Functions.create_function(:run_task) do
|
|
68
69
|
executor.report_function_call(self.class.name)
|
69
70
|
end
|
70
71
|
|
71
|
-
# Report Analytics for bundled content, this should capture tasks run from
|
72
|
+
# Report Analytics for bundled content, this should capture tasks run from
|
73
|
+
# both CLI and Plans.
|
72
74
|
executor.report_bundled_content('Task', task_name)
|
73
75
|
|
74
|
-
# Ensure that given targets are all Target instances
|
76
|
+
# Ensure that given targets are all Target instances.
|
75
77
|
targets = inventory.get_targets(targets)
|
76
78
|
|
77
|
-
|
79
|
+
# Return early if there are no targets.
|
80
|
+
if targets.empty?
|
81
|
+
return Bolt::ResultSet.new([])
|
82
|
+
end
|
78
83
|
|
79
|
-
#
|
80
|
-
|
81
|
-
|
82
|
-
task = Bolt::Task.new(task_name,
|
84
|
+
# If all targets use the PCP transport, create a fake task instead of
|
85
|
+
# loading the actual task definition.
|
86
|
+
if targets.all? { |t| t.transport == 'pcp' }
|
87
|
+
task = Bolt::Task.new(task_name,
|
88
|
+
{ 'supports_noop' => true },
|
89
|
+
[{ 'name' => '', 'path' => '' }])
|
83
90
|
else
|
84
91
|
# TODO: use the compiler injection once PUP-8237 lands
|
85
92
|
task_signature = Puppet::Pal::ScriptCompiler.new(closure_scope.compiler).task_signature(task_name)
|
@@ -89,7 +96,8 @@ Puppet::Functions.create_function(:run_task) do
|
|
89
96
|
|
90
97
|
task = Bolt::Task.from_task_signature(task_signature)
|
91
98
|
|
92
|
-
# Set the default value for any params that have one and were not provided
|
99
|
+
# Set the default value for any params that have one and were not provided
|
100
|
+
# or are undef.
|
93
101
|
params = task.parameter_defaults.merge(params) do |_, default, passed|
|
94
102
|
passed.nil? ? default : passed
|
95
103
|
end
|
@@ -99,9 +107,9 @@ Puppet::Functions.create_function(:run_task) do
|
|
99
107
|
end || (raise with_stack(:TYPE_MISMATCH, 'Task parameters do not match'))
|
100
108
|
end
|
101
109
|
|
110
|
+
# Generate a helpful error message about the type-mismatch between the type
|
111
|
+
# Data and the actual type of params.
|
102
112
|
unless Puppet::Pops::Types::TypeFactory.data.instance?(params)
|
103
|
-
# generate a helpful error message about the type-mismatch between the type Data
|
104
|
-
# and the actual type of params
|
105
113
|
params_t = Puppet::Pops::Types::TypeCalculator.infer_set(params)
|
106
114
|
desc = Puppet::Pops::Types::TypeMismatchDescriber.singleton.describe_mismatch(
|
107
115
|
'Task parameters are not of type Data. run_task()',
|
@@ -133,23 +141,20 @@ Puppet::Functions.create_function(:run_task) do
|
|
133
141
|
# Report whether the task was run in noop mode.
|
134
142
|
executor.report_noop_mode(executor.noop || options[:noop])
|
135
143
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
140
|
-
result = if executor.in_parallel?
|
141
|
-
executor.run_in_thread do
|
142
|
-
executor.run_task(targets, task, params, options, file_line)
|
143
|
-
end
|
144
|
-
else
|
144
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
145
|
+
result = if executor.in_parallel?
|
146
|
+
executor.run_in_thread do
|
145
147
|
executor.run_task(targets, task, params, options, file_line)
|
146
148
|
end
|
149
|
+
else
|
150
|
+
executor.run_task(targets, task, params, options, file_line)
|
151
|
+
end
|
147
152
|
|
148
|
-
|
149
|
-
|
150
|
-
end
|
151
|
-
result
|
153
|
+
if !result.ok && !options[:catch_errors]
|
154
|
+
raise Bolt::RunFailure.new(result, 'run_task', task_name)
|
152
155
|
end
|
156
|
+
|
157
|
+
result
|
153
158
|
end
|
154
159
|
|
155
160
|
def with_stack(kind, msg)
|
@@ -92,10 +92,17 @@ Puppet::Functions.create_function(:run_task_with) do
|
|
92
92
|
# Get all the targets
|
93
93
|
targets = Array(inventory.get_targets(targets))
|
94
94
|
|
95
|
+
# Return early if there are no targets.
|
96
|
+
if targets.empty?
|
97
|
+
return Bolt::ResultSet.new([])
|
98
|
+
end
|
99
|
+
|
95
100
|
# If all targets use the 'pcp' transport, use a fake task instead of loading the local definition
|
96
101
|
# Otherwise, load the local task definition
|
97
|
-
if (pcp_only = targets.
|
98
|
-
task = Bolt::Task.new(task_name,
|
102
|
+
if (pcp_only = targets.all? { |t| t.transport == 'pcp' })
|
103
|
+
task = Bolt::Task.new(task_name,
|
104
|
+
{ 'supports_noop' => true },
|
105
|
+
[{ 'name' => '', 'path' => '' }])
|
99
106
|
else
|
100
107
|
task_signature = Puppet::Pal::ScriptCompiler.new(closure_scope.compiler).task_signature(task_name)
|
101
108
|
|
@@ -178,27 +185,23 @@ Puppet::Functions.create_function(:run_task_with) do
|
|
178
185
|
# Report whether the task was run in noop mode.
|
179
186
|
executor.report_noop_mode(executor.noop || options[:noop])
|
180
187
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
187
|
-
task_result = if executor.in_parallel?
|
188
|
-
executor.run_in_thread do
|
189
|
-
executor.run_task_with(target_mapping, task, options, file_line)
|
190
|
-
end
|
191
|
-
else
|
188
|
+
# Combine the results from the task run with any failing results that were
|
189
|
+
# generated earlier when creating the target mapping
|
190
|
+
file_line = Puppet::Pops::PuppetStack.top_of_stack
|
191
|
+
task_result = if executor.in_parallel?
|
192
|
+
executor.run_in_thread do
|
192
193
|
executor.run_task_with(target_mapping, task, options, file_line)
|
193
194
|
end
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
end
|
195
|
+
else
|
196
|
+
executor.run_task_with(target_mapping, task, options, file_line)
|
197
|
+
end
|
198
|
+
result = Bolt::ResultSet.new(task_result.results + error_set)
|
199
199
|
|
200
|
-
|
200
|
+
if !result.ok && !options[:catch_errors]
|
201
|
+
raise Bolt::RunFailure.new(result, 'run_task', task_name)
|
201
202
|
end
|
203
|
+
|
204
|
+
result
|
202
205
|
end
|
203
206
|
|
204
207
|
def with_stack(kind, msg)
|
data/lib/bolt/application.rb
CHANGED
@@ -49,7 +49,7 @@ module Bolt
|
|
49
49
|
code
|
50
50
|
end
|
51
51
|
|
52
|
-
targets = inventory.get_targets(targets)
|
52
|
+
targets = inventory.get_targets(targets, ext_glob: true)
|
53
53
|
|
54
54
|
Puppet[:tasks] = false
|
55
55
|
ast = pal.parse_manifest(manifest_code, manifest)
|
@@ -90,7 +90,7 @@ module Bolt
|
|
90
90
|
# @return [Bolt::ResultSet]
|
91
91
|
#
|
92
92
|
def run_command(command, targets, env_vars: nil)
|
93
|
-
targets = inventory.get_targets(targets)
|
93
|
+
targets = inventory.get_targets(targets, ext_glob: true)
|
94
94
|
|
95
95
|
with_benchmark do
|
96
96
|
executor.run_command(targets, command, env_vars: env_vars)
|
@@ -106,7 +106,7 @@ module Bolt
|
|
106
106
|
#
|
107
107
|
def download_file(source, destination, targets)
|
108
108
|
destination = File.expand_path(destination, Dir.pwd)
|
109
|
-
targets = inventory.get_targets(targets)
|
109
|
+
targets = inventory.get_targets(targets, ext_glob: true)
|
110
110
|
|
111
111
|
with_benchmark do
|
112
112
|
executor.download_file(targets, source, destination)
|
@@ -122,7 +122,7 @@ module Bolt
|
|
122
122
|
#
|
123
123
|
def upload_file(source, destination, targets)
|
124
124
|
source = find_file(source)
|
125
|
-
targets = inventory.get_targets(targets)
|
125
|
+
targets = inventory.get_targets(targets, ext_glob: true)
|
126
126
|
|
127
127
|
Bolt::Util.validate_file('source file', source, true)
|
128
128
|
|
@@ -225,7 +225,7 @@ module Bolt
|
|
225
225
|
|
226
226
|
with_benchmark do
|
227
227
|
pal.lookup(key,
|
228
|
-
inventory.get_targets(targets),
|
228
|
+
inventory.get_targets(targets, ext_glob: true),
|
229
229
|
inventory,
|
230
230
|
executor,
|
231
231
|
plan_vars: vars)
|
@@ -351,6 +351,7 @@ module Bolt
|
|
351
351
|
# @return [Bolt::PlanResult]
|
352
352
|
#
|
353
353
|
def run_plan(plan, targets, params: {})
|
354
|
+
plan_params = pal.get_plan_info(plan)['parameters']
|
354
355
|
if targets && targets.any?
|
355
356
|
if params['nodes'] || params['targets']
|
356
357
|
key = params.include?('nodes') ? 'nodes' : 'targets'
|
@@ -360,7 +361,6 @@ module Bolt
|
|
360
361
|
"in the JSON data passed in the --params option"
|
361
362
|
end
|
362
363
|
|
363
|
-
plan_params = pal.get_plan_info(plan)['parameters']
|
364
364
|
target_param = plan_params.dig('targets', 'type') =~ /TargetSpec/
|
365
365
|
node_param = plan_params.include?('nodes')
|
366
366
|
|
@@ -375,13 +375,17 @@ module Bolt
|
|
375
375
|
end
|
376
376
|
end
|
377
377
|
|
378
|
-
|
378
|
+
sensitive_params = params.keys.select { |param| plan_params.dig(param, 'sensitive') }
|
379
|
+
|
380
|
+
plan_context = { plan_name: plan, params: params, sensitive: sensitive_params }
|
379
381
|
|
380
382
|
executor.start_plan(plan_context)
|
381
383
|
result = pal.run_plan(plan, params, executor, inventory, plugins.puppetdb_client)
|
382
384
|
executor.finish_plan(result)
|
383
385
|
|
384
386
|
result
|
387
|
+
rescue Bolt::Error => e
|
388
|
+
Bolt::PlanResult.new(e, 'failure')
|
385
389
|
end
|
386
390
|
|
387
391
|
# Show plan information.
|
@@ -620,7 +624,10 @@ module Bolt
|
|
620
624
|
Bolt::Util.validate_file('script', script)
|
621
625
|
|
622
626
|
with_benchmark do
|
623
|
-
executor.run_script(inventory.get_targets(targets
|
627
|
+
executor.run_script(inventory.get_targets(targets, ext_glob: true),
|
628
|
+
script,
|
629
|
+
arguments,
|
630
|
+
env_vars: env_vars)
|
624
631
|
end
|
625
632
|
end
|
626
633
|
|
@@ -676,7 +683,7 @@ module Bolt
|
|
676
683
|
# @return [Bolt::ResultSet]
|
677
684
|
#
|
678
685
|
def run_task(task, targets, params: {})
|
679
|
-
targets = inventory.get_targets(targets)
|
686
|
+
targets = inventory.get_targets(targets, ext_glob: true)
|
680
687
|
|
681
688
|
with_benchmark do
|
682
689
|
pal.run_task(task, targets, params, executor, inventory)
|
@@ -775,7 +782,7 @@ module Bolt
|
|
775
782
|
# Retrieve the known group and target names. This needs to be done before
|
776
783
|
# updating targets, as that will add adhoc targets to the inventory.
|
777
784
|
known_names = inventory.target_names
|
778
|
-
targets = inventory.get_targets(targets)
|
785
|
+
targets = inventory.get_targets(targets, ext_glob: true)
|
779
786
|
|
780
787
|
inventory_targets, adhoc_targets = targets.partition do |target|
|
781
788
|
known_names.include?(target.name)
|
data/lib/bolt/applicator.rb
CHANGED
@@ -162,7 +162,13 @@ module Bolt
|
|
162
162
|
|
163
163
|
def validate_hiera_config(hiera_config)
|
164
164
|
if File.exist?(File.path(hiera_config))
|
165
|
-
data = File.open(File.path(hiera_config), "r:UTF-8")
|
165
|
+
data = File.open(File.path(hiera_config), "r:UTF-8") do |f|
|
166
|
+
if Psych.method(:safe_load).parameters.rassoc(:permitted_classes)
|
167
|
+
YAML.safe_load(f.read, permitted_classes: [Symbol])
|
168
|
+
else
|
169
|
+
YAML.safe_load(f.read, [Symbol])
|
170
|
+
end
|
171
|
+
end
|
166
172
|
if data.nil?
|
167
173
|
return nil
|
168
174
|
elsif data['version'] != 5
|
@@ -219,7 +225,7 @@ module Bolt
|
|
219
225
|
code_ast: ast,
|
220
226
|
modulepath: @modulepath,
|
221
227
|
project: @project.to_h,
|
222
|
-
pdb_config: @pdb_client.config.to_hash,
|
228
|
+
pdb_config: @pdb_client.instance(options[:puppetdb]).config.to_hash,
|
223
229
|
hiera_config: @hiera_config,
|
224
230
|
plan_vars: plan_vars,
|
225
231
|
# This data isn't available on the target config hash
|
@@ -10,7 +10,7 @@ module Bolt
|
|
10
10
|
OPTIONS = { inventory: %w[targets query rerun],
|
11
11
|
authentication: %w[user password password-prompt private-key host-key-check ssl ssl-verify],
|
12
12
|
escalation: %w[run-as sudo-password sudo-password-prompt sudo-executable],
|
13
|
-
run_context: %w[concurrency inventoryfile save-rerun cleanup],
|
13
|
+
run_context: %w[concurrency inventoryfile save-rerun cleanup puppetdb],
|
14
14
|
global_config_setters: PROJECT_PATHS + %w[modulepath],
|
15
15
|
transports: %w[transport connect-timeout tty native-ssh ssh-command copy-command],
|
16
16
|
display: %w[format color verbose trace stream],
|
@@ -1054,6 +1054,9 @@ module Bolt
|
|
1054
1054
|
define('--[no-]save-rerun', 'Whether to update the rerun file after this command.') do |save|
|
1055
1055
|
@options[:'save-rerun'] = save
|
1056
1056
|
end
|
1057
|
+
define('--puppetdb INSTANCE', 'The named PuppetDB instance to connect to by default.') do |instance|
|
1058
|
+
@options[:default_puppetdb] = instance
|
1059
|
+
end
|
1057
1060
|
|
1058
1061
|
separator "\n#{self.class.colorize(:cyan, 'Remote environment options')}"
|
1059
1062
|
define('--env-var ENVIRONMENT_VARIABLES', 'Environment variables to set on the target.') do |envvar|
|
data/lib/bolt/catalog.rb
CHANGED
@@ -56,7 +56,7 @@ module Bolt
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def compile_catalog(request)
|
59
|
-
pdb_client = Bolt::PuppetDB::Client.new(
|
59
|
+
pdb_client = Bolt::PuppetDB::Client.new(config: request['pdb_config'])
|
60
60
|
project = request['project']
|
61
61
|
bolt_project = Struct.new(:name, :path, :load_as_module?).new(project['name'],
|
62
62
|
project['path'],
|
data/lib/bolt/config/options.rb
CHANGED
@@ -54,6 +54,58 @@ module Bolt
|
|
54
54
|
}
|
55
55
|
}.freeze
|
56
56
|
|
57
|
+
# PuppetDB options.
|
58
|
+
PUPPETDB_OPTIONS = {
|
59
|
+
"cacert" => {
|
60
|
+
description: "The path to the ca certificate for PuppetDB.",
|
61
|
+
type: String,
|
62
|
+
_example: "/etc/puppetlabs/puppet/ssl/certs/ca.pem",
|
63
|
+
_plugin: true
|
64
|
+
},
|
65
|
+
"cert" => {
|
66
|
+
description: "The path to the client certificate file to use for authentication.",
|
67
|
+
type: String,
|
68
|
+
_example: "/etc/puppetlabs/puppet/ssl/certs/my-host.example.com.pem",
|
69
|
+
_plugin: true
|
70
|
+
},
|
71
|
+
"connect_timeout" => {
|
72
|
+
description: "How long to wait in seconds when establishing connections with PuppetDB.",
|
73
|
+
type: Integer,
|
74
|
+
minimum: 1,
|
75
|
+
_default: 60,
|
76
|
+
_example: 120,
|
77
|
+
_plugin: true
|
78
|
+
},
|
79
|
+
"key" => {
|
80
|
+
description: "The private key for the certificate.",
|
81
|
+
type: String,
|
82
|
+
_example: "/etc/puppetlabs/puppet/ssl/private_keys/my-host.example.com.pem",
|
83
|
+
_plugin: true
|
84
|
+
},
|
85
|
+
"read_timeout" => {
|
86
|
+
description: "How long to wait in seconds for a response from PuppetDB.",
|
87
|
+
type: Integer,
|
88
|
+
minimum: 1,
|
89
|
+
_default: 60,
|
90
|
+
_example: 120,
|
91
|
+
_plugin: true
|
92
|
+
},
|
93
|
+
"server_urls" => {
|
94
|
+
description: "An array containing the PuppetDB host to connect to. Include the protocol `https` "\
|
95
|
+
"and the port, which is usually `8081`. For example, "\
|
96
|
+
"`https://my-puppetdb-server.com:8081`.",
|
97
|
+
type: Array,
|
98
|
+
_example: ["https://puppet.example.com:8081"],
|
99
|
+
_plugin: true
|
100
|
+
},
|
101
|
+
"token" => {
|
102
|
+
description: "The path to the PE RBAC Token.",
|
103
|
+
type: String,
|
104
|
+
_example: "~/.puppetlabs/token",
|
105
|
+
_plugin: true
|
106
|
+
}
|
107
|
+
}.freeze
|
108
|
+
|
57
109
|
# Definitions used to validate config options.
|
58
110
|
# https://github.com/puppetlabs/bolt/blob/main/schemas/README.md
|
59
111
|
OPTIONS = {
|
@@ -409,55 +461,17 @@ module Bolt
|
|
409
461
|
description: "A map containing options for [configuring the Bolt PuppetDB "\
|
410
462
|
"client](bolt_connect_puppetdb.md).",
|
411
463
|
type: Hash,
|
412
|
-
properties:
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
_plugin: true
|
424
|
-
},
|
425
|
-
"connect_timeout" => {
|
426
|
-
description: "How long to wait in seconds when establishing connections with PuppetDB.",
|
427
|
-
type: Integer,
|
428
|
-
minimum: 1,
|
429
|
-
_default: 60,
|
430
|
-
_example: 120,
|
431
|
-
_plugin: true
|
432
|
-
},
|
433
|
-
"key" => {
|
434
|
-
description: "The private key for the certificate.",
|
435
|
-
type: String,
|
436
|
-
_example: "/etc/puppetlabs/puppet/ssl/private_keys/my-host.example.com.pem",
|
437
|
-
_plugin: true
|
438
|
-
},
|
439
|
-
"read_timeout" => {
|
440
|
-
description: "How long to wait in seconds for a response from PuppetDB.",
|
441
|
-
type: Integer,
|
442
|
-
minimum: 1,
|
443
|
-
_default: 60,
|
444
|
-
_example: 120,
|
445
|
-
_plugin: true
|
446
|
-
},
|
447
|
-
"server_urls" => {
|
448
|
-
description: "An array containing the PuppetDB host to connect to. Include the protocol `https` "\
|
449
|
-
"and the port, which is usually `8081`. For example, "\
|
450
|
-
"`https://my-puppetdb-server.com:8081`.",
|
451
|
-
type: Array,
|
452
|
-
_example: ["https://puppet.example.com:8081"],
|
453
|
-
_plugin: true
|
454
|
-
},
|
455
|
-
"token" => {
|
456
|
-
description: "The path to the PE RBAC Token.",
|
457
|
-
type: String,
|
458
|
-
_example: "~/.puppetlabs/token",
|
459
|
-
_plugin: true
|
460
|
-
}
|
464
|
+
properties: PUPPETDB_OPTIONS,
|
465
|
+
_plugin: true
|
466
|
+
},
|
467
|
+
"puppetdb-instances" => {
|
468
|
+
description: "A map of named PuppetDB instances and their configuration, where keys are the name "\
|
469
|
+
"of a PuppetDB instance and values are maps of configuration options. For more "\
|
470
|
+
"information, see [Connecting Bolt to PuppetDB](bolt_connect_puppetdb.md).",
|
471
|
+
type: Hash,
|
472
|
+
additionalProperties: {
|
473
|
+
type: Hash,
|
474
|
+
properties: PUPPETDB_OPTIONS
|
461
475
|
},
|
462
476
|
_plugin: true
|
463
477
|
},
|
@@ -610,6 +624,7 @@ module Bolt
|
|
610
624
|
plugin-hooks
|
611
625
|
plugins
|
612
626
|
puppetdb
|
627
|
+
puppetdb-instances
|
613
628
|
save-rerun
|
614
629
|
spinner
|
615
630
|
stream
|
@@ -637,6 +652,7 @@ module Bolt
|
|
637
652
|
plugins
|
638
653
|
policies
|
639
654
|
puppetdb
|
655
|
+
puppetdb-instances
|
640
656
|
rerunfile
|
641
657
|
save-rerun
|
642
658
|
spinner
|