bolt 3.22.1 → 3.23.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 +7 -7
- 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/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.rb +12 -3
- data/lib/bolt/outputter/human.rb +8 -3
- data/lib/bolt/pal/yaml_plan/loader.rb +1 -1
- data/lib/bolt/pal.rb +6 -2
- data/lib/bolt/plugin/puppetdb.rb +7 -4
- 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/version.rb +1 -1
- 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 +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b79c90eb580d16111b19753003a7620e530ab9f10a47eb2cc4a5d5f5f1e15e1
|
4
|
+
data.tar.gz: 791076493e0979acd945dd80f6d513eefaaa1170d36f626bf71c1d9a8ff990f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 881675efbe7148a860a49fb4d74d8c8332af588d27526e29a1df99acbeacee0f802e6f0c71c710506bfdd1e6210a82645eaf1cdb1053d52b760318898142ee93
|
7
|
+
data.tar.gz: 316cb92d945be0a2f3287e6dd7e4cee7505af08b8918f539f9b9ee678f7c9e7704d5dbb83f617eab772dc86f4521c93fab8e01778e5348873c8b39488baf3b43
|
data/Puppetfile
CHANGED
@@ -5,14 +5,14 @@ forge "http://forge.puppetlabs.com"
|
|
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
29
|
mod 'puppetlabs-reboot', '4.1.0'
|
30
|
-
mod 'puppetlabs-ruby_task_helper', '0.6.
|
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/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
|
data/lib/bolt/config.rb
CHANGED
@@ -181,6 +181,7 @@ module Bolt
|
|
181
181
|
'plugin-hooks' => {},
|
182
182
|
'plugins' => {},
|
183
183
|
'puppetdb' => {},
|
184
|
+
'puppetdb-instances' => {},
|
184
185
|
'save-rerun' => true,
|
185
186
|
'spinner' => true,
|
186
187
|
'transport' => 'ssh'
|
@@ -225,7 +226,7 @@ module Bolt
|
|
225
226
|
|
226
227
|
# Pull out config options. We need to add 'transport' and 'inventoryfile' as they're
|
227
228
|
# not part of the OPTIONS hash but are valid options that can be set with CLI options
|
228
|
-
overrides = opts.slice(*OPTIONS.keys, 'inventoryfile', 'transport')
|
229
|
+
overrides = opts.slice(*OPTIONS.keys, 'inventoryfile', 'transport', 'default_puppetdb')
|
229
230
|
|
230
231
|
# Pull out transport config options
|
231
232
|
TRANSPORT_CONFIG.each do |transport, config|
|
@@ -252,14 +253,14 @@ module Bolt
|
|
252
253
|
config_data.inject({}) do |acc, config|
|
253
254
|
acc.merge(config) do |key, val1, val2|
|
254
255
|
case key
|
255
|
-
#
|
256
|
+
# Shallow merge config for each plugin
|
256
257
|
when 'plugins'
|
257
258
|
val1.merge(val2) { |_, v1, v2| v1.merge(v2) }
|
258
259
|
# Transports are deep merged
|
259
260
|
when *TRANSPORT_CONFIG.keys
|
260
261
|
Bolt::Util.deep_merge(val1, val2)
|
261
262
|
# Hash values are shallow merged
|
262
|
-
when 'apply-settings', 'log', 'plugin-hooks', 'puppetdb'
|
263
|
+
when 'apply-settings', 'log', 'plugin-hooks', 'puppetdb', 'puppetdb-instances'
|
263
264
|
val1.merge(val2)
|
264
265
|
# Disabled warnings are concatenated
|
265
266
|
when 'disable-warnings'
|
@@ -407,6 +408,14 @@ module Bolt
|
|
407
408
|
@data['puppetdb']
|
408
409
|
end
|
409
410
|
|
411
|
+
def puppetdb_instances
|
412
|
+
@data['puppetdb-instances']
|
413
|
+
end
|
414
|
+
|
415
|
+
def default_puppetdb
|
416
|
+
@data['default_puppetdb']
|
417
|
+
end
|
418
|
+
|
410
419
|
def color
|
411
420
|
@data['color']
|
412
421
|
end
|
data/lib/bolt/outputter/human.rb
CHANGED
@@ -405,10 +405,15 @@ module Bolt
|
|
405
405
|
|
406
406
|
# Add plan name and description
|
407
407
|
info << colorize(:cyan, "#{plan['name']}\n")
|
408
|
-
|
409
|
-
|
410
|
-
|
408
|
+
|
409
|
+
description = +''
|
410
|
+
description << "#{plan['summary']}\n\n" if plan['summary']
|
411
|
+
description << plan['docstring'] if plan['docstring']
|
412
|
+
|
413
|
+
info << if description.empty?
|
411
414
|
indent(2, 'No description available.')
|
415
|
+
else
|
416
|
+
indent(2, description.strip)
|
412
417
|
end
|
413
418
|
info << "\n\n"
|
414
419
|
|
@@ -50,7 +50,7 @@ module Bolt
|
|
50
50
|
def self.parse_plan(yaml_string, source_ref)
|
51
51
|
# This passes the filename as the second arg for compatibility with Psych used with ruby < 2.6
|
52
52
|
# This can be removed when we remove support for ruby 2.5
|
53
|
-
parse_tree = if Psych.method(:parse).parameters.
|
53
|
+
parse_tree = if Psych.method(:parse).parameters.rassoc(:filename) == %i[key filename]
|
54
54
|
Psych.parse(yaml_string, filename: source_ref)
|
55
55
|
else
|
56
56
|
Psych.parse(yaml_string, source_ref)
|
data/lib/bolt/pal.rb
CHANGED
@@ -531,7 +531,9 @@ module Bolt
|
|
531
531
|
'description' => description,
|
532
532
|
'parameters' => parameters,
|
533
533
|
'module' => mod,
|
534
|
-
'private' => private_plan?(plan)
|
534
|
+
'private' => private_plan?(plan),
|
535
|
+
'summary' => plan.tag(:summary)&.text,
|
536
|
+
'docstring' => (plan.docstring unless plan.docstring.empty?)
|
535
537
|
}
|
536
538
|
|
537
539
|
pp_info.merge!(get_plan_mtime(plan.file)) if with_mtime
|
@@ -564,7 +566,9 @@ module Bolt
|
|
564
566
|
'description' => plan.description,
|
565
567
|
'parameters' => parameters,
|
566
568
|
'module' => mod,
|
567
|
-
'private' => !!plan.private
|
569
|
+
'private' => !!plan.private,
|
570
|
+
'docstring' => plan.description,
|
571
|
+
'summary' => nil
|
568
572
|
}
|
569
573
|
|
570
574
|
yaml_info.merge!(get_plan_mtime(yaml_path)) if with_mtime
|