bolt 2.0.1 → 2.1.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 +1 -1
- data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +48 -0
- data/lib/bolt/bolt_option_parser.rb +8 -3
- data/lib/bolt/config.rb +17 -12
- data/lib/bolt/inventory/group.rb +8 -9
- data/lib/bolt/inventory/inventory.rb +34 -10
- data/lib/bolt/inventory/target.rb +9 -7
- data/lib/bolt/pal.rb +8 -3
- data/lib/bolt/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d912a5ba19a113e4e5a57aed09f04f1a72a659b05fdb7cc09164146b59fc0cc
|
4
|
+
data.tar.gz: 9344eaf150b512c769e8b6fd7ac91fef7ece7de62cb39bede4f22ebd15f52cd3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69040995cbcff577cfa377f50a80dc76825ba3aa0fd107788f146c26e5d562131ec089ce79f69c052b47b2fa9b2d7af3c9feb587829e6a4b9297ee9df2b9d9bd
|
7
|
+
data.tar.gz: ef5b45003158f3f4801877e2c19768b990fa4c09d84fcce40888f4236bf025e0244ac5e5e4b5edc5397c3a49691390e650b0724a8450c3e10382fdee44b80f73
|
data/Puppetfile
CHANGED
@@ -25,7 +25,7 @@ mod 'puppetlabs-zone_core', '1.0.3'
|
|
25
25
|
mod 'puppetlabs-package', '0.7.0'
|
26
26
|
mod 'puppetlabs-puppet_conf', '0.4.0'
|
27
27
|
mod 'puppetlabs-python_task_helper', '0.3.0'
|
28
|
-
mod 'puppetlabs-reboot', '
|
28
|
+
mod 'puppetlabs-reboot', '3.0.0'
|
29
29
|
mod 'puppetlabs-ruby_task_helper', '0.4.0'
|
30
30
|
mod 'puppetlabs-ruby_plugin_helper', '0.1.0'
|
31
31
|
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
# Write contents to a file on the given set of targets.
|
6
|
+
#
|
7
|
+
# > **Note:** Not available in apply block
|
8
|
+
Puppet::Functions.create_function(:write_file) do
|
9
|
+
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
|
10
|
+
# @param content File content to write.
|
11
|
+
# @param destination An absolute path on the target(s).
|
12
|
+
# @option options [Boolean] _catch_errors Whether to catch raised errors.
|
13
|
+
# @option options [String] _run_as User to run as using privilege escalation.
|
14
|
+
# @return A list of results, one entry per target.
|
15
|
+
# @example Write a file to a target
|
16
|
+
# $content = 'Hello, world!'
|
17
|
+
# write_file($targets, $content, '/Users/me/hello.txt')
|
18
|
+
dispatch :write_file do
|
19
|
+
required_param 'String', :content
|
20
|
+
required_param 'String[1]', :destination
|
21
|
+
required_param 'Boltlib::TargetSpec', :targets
|
22
|
+
optional_param 'Hash[String[1], Any]', :options
|
23
|
+
return_type 'ResultSet'
|
24
|
+
end
|
25
|
+
|
26
|
+
def write_file(content, destination, target_spec, options = {})
|
27
|
+
unless Puppet[:tasks]
|
28
|
+
raise Puppet::ParseErrorWithIssue
|
29
|
+
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING,
|
30
|
+
action: 'write_file')
|
31
|
+
end
|
32
|
+
|
33
|
+
executor = Puppet.lookup(:bolt_executor)
|
34
|
+
executor.report_function_call(self.class.name)
|
35
|
+
|
36
|
+
inventory = Puppet.lookup(:bolt_inventory)
|
37
|
+
targets = inventory.get_targets(target_spec)
|
38
|
+
|
39
|
+
executor.log_action("write file #{destination}", targets) do
|
40
|
+
executor.without_default_logging do
|
41
|
+
Tempfile.create do |tmp|
|
42
|
+
call_function('file::write', tmp.path, content)
|
43
|
+
call_function('upload_file', tmp.path, destination, targets, options)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -88,7 +88,7 @@ module Bolt
|
|
88
88
|
when 'puppetfile'
|
89
89
|
case action
|
90
90
|
when 'install'
|
91
|
-
{ flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
|
91
|
+
{ flags: OPTIONS[:global] + OPTIONS[:global_config_setters] + %w[puppetfile],
|
92
92
|
banner: PUPPETFILE_INSTALL_HELP }
|
93
93
|
when 'show-modules'
|
94
94
|
{ flags: OPTIONS[:global] + OPTIONS[:global_config_setters],
|
@@ -706,7 +706,7 @@ module Bolt
|
|
706
706
|
@options[:boltdir] = path
|
707
707
|
end
|
708
708
|
define('--configfile FILEPATH',
|
709
|
-
'Specify where to load config from (default: ~/.puppetlabs/bolt/bolt.yaml).
|
709
|
+
'Specify where to load config from (default: ~/.puppetlabs/bolt/bolt.yaml).',
|
710
710
|
'Directory containing bolt.yaml will be used as the Boltdir.') do |path|
|
711
711
|
@options[:configfile] = path
|
712
712
|
end
|
@@ -715,7 +715,12 @@ module Bolt
|
|
715
715
|
if ENV.include?(Bolt::Inventory::ENVIRONMENT_VAR)
|
716
716
|
raise Bolt::CLIError, "Cannot pass inventory file when #{Bolt::Inventory::ENVIRONMENT_VAR} is set"
|
717
717
|
end
|
718
|
-
@options[:inventoryfile] = File.expand_path(path)
|
718
|
+
@options[:inventoryfile] = Pathname.new(File.expand_path(path))
|
719
|
+
end
|
720
|
+
define('--puppetfile FILEPATH',
|
721
|
+
'Specify a Puppetfile to use when installing modules. (default: ~/.puppetlabs/bolt/Puppetfile)',
|
722
|
+
'Modules are installed in the current Boltdir.') do |path|
|
723
|
+
@options[:puppetfile] = Pathname.new(File.expand_path(path))
|
719
724
|
end
|
720
725
|
define('--[no-]save-rerun', 'Whether to update the rerun file after this command.') do |save|
|
721
726
|
@options[:'save-rerun'] = save
|
data/lib/bolt/config.rb
CHANGED
@@ -223,12 +223,6 @@ module Bolt
|
|
223
223
|
Bolt::Util.deep_clone(self)
|
224
224
|
end
|
225
225
|
|
226
|
-
def normalize_interpreters(interpreters)
|
227
|
-
Bolt::Util.walk_keys(interpreters) do |key|
|
228
|
-
key.chars[0] == '.' ? key : '.' + key
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
226
|
def normalize_log(target)
|
233
227
|
return target if target == 'console'
|
234
228
|
target = target[5..-1] if target.start_with?('file:')
|
@@ -308,6 +302,8 @@ module Bolt
|
|
308
302
|
send("#{key}=", options[key]) if options.key?(key)
|
309
303
|
end
|
310
304
|
|
305
|
+
@puppetfile = options[:puppetfile] if options.key?(:puppetfile)
|
306
|
+
|
311
307
|
@save_rerun = options[:'save-rerun'] if options.key?(:'save-rerun')
|
312
308
|
|
313
309
|
if options[:debug]
|
@@ -345,6 +341,11 @@ module Bolt
|
|
345
341
|
end
|
346
342
|
|
347
343
|
def update_transports(data)
|
344
|
+
self.class.update_transport_hash(@boltdir.path, @transports, data)
|
345
|
+
@transport = data['transport'] if data.key?('transport')
|
346
|
+
end
|
347
|
+
|
348
|
+
def self.update_transport_hash(boltdir, existing, data)
|
348
349
|
TRANSPORTS.each do |key, impl|
|
349
350
|
if data[key.to_s]
|
350
351
|
selected = impl.filter_options(data[key.to_s])
|
@@ -352,17 +353,21 @@ module Bolt
|
|
352
353
|
# Expand file paths relative to the Boltdir
|
353
354
|
to_expand = %w[private-key cacert token-file] & selected.keys
|
354
355
|
to_expand.each do |opt|
|
355
|
-
selected[opt] = File.expand_path(selected[opt],
|
356
|
+
selected[opt] = File.expand_path(selected[opt], boltdir) if selected[opt].is_a?(String)
|
356
357
|
end
|
357
358
|
|
358
|
-
|
359
|
+
existing[key] = Bolt::Util.deep_merge(existing[key], selected)
|
359
360
|
end
|
360
|
-
if
|
361
|
-
|
361
|
+
if existing[key]['interpreters']
|
362
|
+
existing[key]['interpreters'] = normalize_interpreters(existing[key]['interpreters'])
|
362
363
|
end
|
363
364
|
end
|
365
|
+
end
|
364
366
|
|
365
|
-
|
367
|
+
def self.normalize_interpreters(interpreters)
|
368
|
+
Bolt::Util.walk_keys(interpreters) do |key|
|
369
|
+
key.chars[0] == '.' ? key : '.' + key
|
370
|
+
end
|
366
371
|
end
|
367
372
|
|
368
373
|
def transport_conf
|
@@ -383,7 +388,7 @@ module Bolt
|
|
383
388
|
end
|
384
389
|
|
385
390
|
def puppetfile
|
386
|
-
@boltdir.puppetfile
|
391
|
+
@puppetfile || @boltdir.puppetfile
|
387
392
|
end
|
388
393
|
|
389
394
|
def modulepath
|
data/lib/bolt/inventory/group.rb
CHANGED
@@ -116,7 +116,7 @@ module Bolt
|
|
116
116
|
raise ValidationError.new("Target name must be ASCII characters: #{target}", @name)
|
117
117
|
end
|
118
118
|
|
119
|
-
if
|
119
|
+
if contains_target?(t_name)
|
120
120
|
@logger.warn("Ignoring duplicate target in #{@name}: #{target}")
|
121
121
|
return
|
122
122
|
end
|
@@ -189,9 +189,6 @@ module Bolt
|
|
189
189
|
end
|
190
190
|
|
191
191
|
def resolve_string_targets(aliases, known_targets)
|
192
|
-
# Use a single copy of this because recomputing it for every target is
|
193
|
-
# prohibitively expensive for large groups
|
194
|
-
cached_local_targets = local_targets
|
195
192
|
@string_targets.each do |string_target|
|
196
193
|
# If this is the name of a target defined elsewhere, then insert the
|
197
194
|
# target into this group as just a name. Otherwise, add a new target
|
@@ -200,19 +197,17 @@ module Bolt
|
|
200
197
|
@unresolved_targets[string_target] = { 'name' => string_target }
|
201
198
|
# If this is an alias for an existing target, then add it to this group
|
202
199
|
elsif (canonical_name = aliases[string_target])
|
203
|
-
if
|
200
|
+
if contains_target?(canonical_name)
|
204
201
|
@logger.warn("Ignoring duplicate target in #{@name}: #{canonical_name}")
|
205
202
|
else
|
206
203
|
@unresolved_targets[canonical_name] = { 'name' => canonical_name }
|
207
|
-
cached_local_targets << canonical_name
|
208
204
|
end
|
209
205
|
# If it's not the name or alias of an existing target, then make a
|
210
206
|
# new target using the string as the URI
|
211
|
-
elsif
|
207
|
+
elsif contains_target?(string_target)
|
212
208
|
@logger.warn("Ignoring duplicate target in #{@name}: #{string_target}")
|
213
209
|
else
|
214
210
|
@unresolved_targets[string_target] = { 'uri' => string_target }
|
215
|
-
cached_local_targets << string_target
|
216
211
|
end
|
217
212
|
end
|
218
213
|
@groups.each { |g| g.resolve_string_targets(aliases, known_targets) }
|
@@ -364,6 +359,10 @@ module Bolt
|
|
364
359
|
Set.new(@unresolved_targets.keys) + Set.new(@resolved_targets.keys)
|
365
360
|
end
|
366
361
|
|
362
|
+
def contains_target?(target_name)
|
363
|
+
@unresolved_targets.key?(target_name) || @resolved_targets.key?(target_name)
|
364
|
+
end
|
365
|
+
|
367
366
|
# Returns all targets contained within the group, which includes targets from subgroups.
|
368
367
|
def all_targets
|
369
368
|
@groups.inject(local_targets) do |acc, g|
|
@@ -404,7 +403,7 @@ module Bolt
|
|
404
403
|
|
405
404
|
# If this group has the target or one of the child groups has the
|
406
405
|
# target, return the data, otherwise return nil
|
407
|
-
if child_result ||
|
406
|
+
if child_result || contains_target?(target_name)
|
408
407
|
# Children override the parent
|
409
408
|
data_merge(group_data, child_result)
|
410
409
|
end
|
@@ -168,7 +168,6 @@ module Bolt
|
|
168
168
|
def add_target(current_group, target, desired_group)
|
169
169
|
if current_group.name == desired_group
|
170
170
|
current_group.add_target(target)
|
171
|
-
@groups.validate
|
172
171
|
target.invalidate_group_cache!
|
173
172
|
return true
|
174
173
|
end
|
@@ -200,6 +199,8 @@ module Bolt
|
|
200
199
|
# If target already exists, delete old and replace with new, otherwise add to new to all group
|
201
200
|
new_target = Bolt::Inventory::Target.new(data, self)
|
202
201
|
existing_target = @targets.key?(new_target.name)
|
202
|
+
|
203
|
+
validate_target_from_hash(new_target)
|
203
204
|
@targets[new_target.name] = new_target
|
204
205
|
|
205
206
|
if existing_target
|
@@ -208,17 +209,43 @@ module Bolt
|
|
208
209
|
add_to_group([new_target], 'all')
|
209
210
|
end
|
210
211
|
|
211
|
-
if
|
212
|
-
|
213
|
-
|
212
|
+
if new_target.target_alias
|
213
|
+
@groups.insert_alia(new_target.name, Array(new_target.target_alias))
|
214
|
+
end
|
215
|
+
|
216
|
+
new_target
|
217
|
+
end
|
218
|
+
|
219
|
+
def validate_target_from_hash(target)
|
220
|
+
groups = Set.new(group_names)
|
221
|
+
targets = target_names
|
222
|
+
|
223
|
+
# Make sure there are no group name conflicts
|
224
|
+
if groups.include?(target.name)
|
225
|
+
raise ValidationError.new("Target name #{target.name} conflicts with group of the same name", nil)
|
226
|
+
end
|
227
|
+
|
228
|
+
# Validate any aliases
|
229
|
+
if (aliases = target.target_alias)
|
230
|
+
unless aliases.is_a?(Array) || aliases.is_a?(String)
|
214
231
|
msg = "Alias entry on #{t_name} must be a String or Array, not #{aliases.class}"
|
215
232
|
raise ValidationError.new(msg, @name)
|
216
233
|
end
|
217
|
-
|
218
|
-
@groups.insert_alia(new_target.name, aliases)
|
219
234
|
end
|
220
235
|
|
221
|
-
|
236
|
+
# Make sure there are no conflicts with the new target aliases
|
237
|
+
used_aliases = @groups.target_aliases
|
238
|
+
Array(target.target_alias).each do |alia|
|
239
|
+
if groups.include?(alia)
|
240
|
+
raise ValidationError.new("Alias #{alia} conflicts with group of the same name", nil)
|
241
|
+
elsif targets.include?(alia)
|
242
|
+
raise ValidationError.new("Alias #{alia} conflicts with target of the same name", nil)
|
243
|
+
elsif used_aliases[alia] && used_aliases[alia] != target.name
|
244
|
+
raise ValidationError.new(
|
245
|
+
"Alias #{alia} refers to multiple targets: #{used_aliases[alia]} and #{target.name}", nil
|
246
|
+
)
|
247
|
+
end
|
248
|
+
end
|
222
249
|
end
|
223
250
|
|
224
251
|
def clear_alia_from_group(group, target_name)
|
@@ -249,9 +276,6 @@ module Bolt
|
|
249
276
|
def add_to_group(targets, desired_group)
|
250
277
|
if group_names.include?(desired_group)
|
251
278
|
targets.each do |target|
|
252
|
-
if group_names.include?(target.name)
|
253
|
-
raise ValidationError.new("Group #{target.name} conflicts with target of the same name", target.name)
|
254
|
-
end
|
255
279
|
# Add the inventory copy of the target
|
256
280
|
add_target(@groups, @targets[target.name], desired_group)
|
257
281
|
end
|
@@ -109,14 +109,16 @@ module Bolt
|
|
109
109
|
def transport_config_cache
|
110
110
|
if @transport_config_cache.nil?
|
111
111
|
merged_config = Bolt::Util.deep_merge(group_cache['config'], @config)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
112
|
+
base_config = @inventory.config
|
113
|
+
transport_data = Bolt::Util.deep_clone(base_config.transports)
|
114
|
+
Bolt::Config.update_transport_hash(base_config.boltdir.path, transport_data, merged_config)
|
115
|
+
transport = merged_config['transport'] || base_config.transport
|
116
|
+
Bolt::TRANSPORTS.each do |name, impl|
|
117
|
+
impl.validate(transport_data[name])
|
118
|
+
end
|
117
119
|
@transport_config_cache = {
|
118
|
-
'transport' =>
|
119
|
-
'transports' =>
|
120
|
+
'transport' => transport,
|
121
|
+
'transports' => transport_data
|
120
122
|
}
|
121
123
|
end
|
122
124
|
|
data/lib/bolt/pal.rb
CHANGED
@@ -336,11 +336,16 @@ module Bolt
|
|
336
336
|
end
|
337
337
|
|
338
338
|
defaults = plan.parameters.reject { |_, value| value.nil? }.to_h
|
339
|
+
signature_params = Set.new(plan.parameters.map(&:first))
|
339
340
|
parameters = plan.tags(:param).each_with_object({}) do |param, params|
|
340
341
|
name = param.name
|
341
|
-
|
342
|
-
|
343
|
-
|
342
|
+
if signature_params.include?(name)
|
343
|
+
params[name] = { 'type' => param.types.first }
|
344
|
+
params[name]['default_value'] = defaults[name] if defaults.key?(name)
|
345
|
+
params[name]['description'] = param.text unless param.text.empty?
|
346
|
+
else
|
347
|
+
@logger.warn("The documented parameter '#{name}' does not exist in plan signature")
|
348
|
+
end
|
344
349
|
end
|
345
350
|
|
346
351
|
{
|
data/lib/bolt/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bolt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Puppet
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02
|
11
|
+
date: 2020-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -375,6 +375,7 @@ files:
|
|
375
375
|
- bolt-modules/boltlib/lib/puppet/functions/vars.rb
|
376
376
|
- bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb
|
377
377
|
- bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb
|
378
|
+
- bolt-modules/boltlib/lib/puppet/functions/write_file.rb
|
378
379
|
- bolt-modules/boltlib/types/planresult.pp
|
379
380
|
- bolt-modules/boltlib/types/targetspec.pp
|
380
381
|
- bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb
|