bolt 1.32.0 → 1.33.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.

Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +3 -0
  3. data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +6 -5
  4. data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +14 -13
  5. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +8 -6
  6. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +24 -24
  7. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +6 -5
  8. data/lib/bolt/applicator.rb +7 -6
  9. data/lib/bolt/cli.rb +2 -2
  10. data/lib/bolt/executor.rb +9 -9
  11. data/lib/bolt/outputter/human.rb +5 -5
  12. data/lib/bolt/plugin.rb +2 -1
  13. data/lib/bolt/plugin/module.rb +1 -1
  14. data/lib/bolt/plugin/pkcs7.rb +2 -2
  15. data/lib/bolt/plugin/task.rb +1 -1
  16. data/lib/bolt/result_set.rb +8 -0
  17. data/lib/bolt/target.rb +9 -6
  18. data/lib/bolt/task/run.rb +1 -1
  19. data/lib/bolt/transport/base.rb +4 -4
  20. data/lib/bolt/transport/docker/connection.rb +5 -3
  21. data/lib/bolt/transport/local/shell.rb +1 -0
  22. data/lib/bolt/transport/local_windows.rb +2 -1
  23. data/lib/bolt/transport/orch.rb +1 -1
  24. data/lib/bolt/transport/orch/connection.rb +1 -1
  25. data/lib/bolt/transport/ssh.rb +1 -1
  26. data/lib/bolt/transport/ssh/connection.rb +10 -15
  27. data/lib/bolt/transport/sudoable.rb +4 -4
  28. data/lib/bolt/transport/sudoable/connection.rb +1 -1
  29. data/lib/bolt/transport/winrm.rb +1 -1
  30. data/lib/bolt/transport/winrm/connection.rb +7 -13
  31. data/lib/bolt/version.rb +1 -1
  32. data/lib/bolt_spec/plans/action_stubs/command_stub.rb +2 -1
  33. data/lib/bolt_spec/plans/action_stubs/script_stub.rb +1 -0
  34. data/lib/bolt_spec/plans/action_stubs/task_stub.rb +1 -0
  35. data/lib/bolt_spec/plans/action_stubs/upload_stub.rb +2 -1
  36. data/lib/bolt_spec/run.rb +1 -1
  37. data/lib/plan_executor/executor.rb +4 -4
  38. data/lib/plan_executor/orch_client.rb +1 -1
  39. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40fdd97c4150459a56f711d9ece1e1c0b57ff19c4e64ddb88459ea947bf4bbab
4
- data.tar.gz: d2079c900a66e50d0bd9cccd17da37ab965686c6b6c9402b262f148ba2549c44
3
+ metadata.gz: 8529a13b894e496846dd0720d8980e98b4fa6146216089e7792e30ece43e7e17
4
+ data.tar.gz: 319d8cfe5375164d4c94868131a8b5a048d3b8b7b95e45e892e79a470ec4b8d9
5
5
  SHA512:
6
- metadata.gz: bd59adfaa8bb6178de571eef84a08f124666ca94abb9a2a0550127ff105dc7c55e47ba789f9d09c1eae33a517dd4baaf95fce21543dc77bdedfb35c9472ffe88
7
- data.tar.gz: 7f80fcb3d13a832338ab4da986d2ac25bdfbf67785f3fd863692cbd4eb018a30e7a687020c8d7c551ec1f58da9abefadbcd3976820c3d83a3c1cdfd9efb79f47
6
+ metadata.gz: 12b4179334e1849115a5648148193c7aab3da768061ce17b4694c35fa836ccb7184258dca2a3376e0a7bca8c9edbe1439d49f5a1f3e3a30929bd67a7ea5e0930
7
+ data.tar.gz: b57dc487c0ae46c76206a51f9ed27a1791595e8eab63aa9701f1dcc0785e2b52dc051900109b7f3a74d4a7d9ba1b507b879f5fca4a6b9611737e0e092588dc88
@@ -17,6 +17,9 @@ Puppet::DataTypes.create_type('ResultSet') do
17
17
  ok_set => Callable[[], ResultSet],
18
18
  targets => Callable[[], Array[Target]],
19
19
  to_data => Callable[[], Array[Hash]],
20
+ '[]' => Variant[Callable[[Integer], Optional[Variant[Result, ApplyResult, Array[Variant[Result, ApplyResult]]]]],
21
+ Callable[[Integer, Integer], Optional[Variant[Result, ApplyResult, Array[Variant[Result, ApplyResult]]]]]
22
+ ]
20
23
  }
21
24
  PUPPET
22
25
 
@@ -37,18 +37,19 @@ Puppet::Functions.create_function(:run_command) do
37
37
  return_type 'ResultSet'
38
38
  end
39
39
 
40
- def run_command(command, targets, options = nil)
40
+ def run_command(command, targets, options = {})
41
41
  run_command_with_description(command, targets, nil, options)
42
42
  end
43
43
 
44
- def run_command_with_description(command, targets, description = nil, options = nil)
44
+ def run_command_with_description(command, targets, description = nil, options = {})
45
45
  unless Puppet[:tasks]
46
46
  raise Puppet::ParseErrorWithIssue
47
47
  .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_command')
48
48
  end
49
49
 
50
- options ||= {}
51
- options = options.merge('_description' => description) if description
50
+ options = options.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
51
+ options[:description] = description if description
52
+
52
53
  executor = Puppet.lookup(:bolt_executor)
53
54
  inventory = Puppet.lookup(:bolt_inventory)
54
55
 
@@ -64,7 +65,7 @@ Puppet::Functions.create_function(:run_command) do
64
65
  r = executor.run_command(targets, command, options)
65
66
  end
66
67
 
67
- if !r.ok && !options['_catch_errors']
68
+ if !r.ok && !options[:catch_errors]
68
69
  raise Bolt::RunFailure.new(r, 'run_command', command)
69
70
  end
70
71
  r
@@ -8,20 +8,20 @@ require 'bolt/error'
8
8
  Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction) do
9
9
  # Run a plan
10
10
  # @param plan_name The plan to run.
11
- # @param named_args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
11
+ # @param args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
12
12
  # @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
13
13
  # @example Run a plan
14
14
  # run_plan('canary', 'command' => 'false', 'nodes' => $targets, '_catch_errors' => true)
15
15
  dispatch :run_plan do
16
16
  scope_param
17
17
  param 'String', :plan_name
18
- optional_param 'Hash', :named_args
18
+ optional_param 'Hash', :args
19
19
  return_type 'Boltlib::PlanResult'
20
20
  end
21
21
 
22
22
  # Run a plan, specifying $nodes as a positional argument.
23
23
  # @param plan_name The plan to run.
24
- # @param named_args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
24
+ # @param args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
25
25
  # @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
26
26
  # @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
27
27
  # @example Run a plan
@@ -30,21 +30,21 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
30
30
  scope_param
31
31
  param 'String', :plan_name
32
32
  param 'Boltlib::TargetSpec', :targets
33
- optional_param 'Hash', :named_args
33
+ optional_param 'Hash', :args
34
34
  return_type 'Boltlib::PlanResult'
35
35
  end
36
36
 
37
- def run_plan_with_targetspec(scope, plan_name, targets, named_args = {})
38
- unless named_args['nodes'].nil?
37
+ def run_plan_with_targetspec(scope, plan_name, targets, args = {})
38
+ unless args['nodes'].nil?
39
39
  raise ArgumentError,
40
40
  "A plan's 'nodes' parameter may be specified as the second positional argument to " \
41
41
  "run_plan(), but in that case 'nodes' must not be specified in the named arguments " \
42
42
  "hash."
43
43
  end
44
- run_plan(scope, plan_name, named_args.merge('nodes' => targets))
44
+ run_plan(scope, plan_name, args.merge('nodes' => targets))
45
45
  end
46
46
 
47
- def run_plan(scope, plan_name, named_args = {})
47
+ def run_plan(scope, plan_name, args = {})
48
48
  unless Puppet[:tasks]
49
49
  raise Puppet::ParseErrorWithIssue
50
50
  .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_plan')
@@ -52,17 +52,18 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
52
52
 
53
53
  executor = Puppet.lookup(:bolt_executor)
54
54
 
55
+ options, params = args.partition { |k, _v| k.start_with?('_') }.map(&:to_h)
56
+ options = options.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
57
+
55
58
  # Bolt calls this function internally to trigger plans from the CLI. We
56
59
  # don't want to count those invocations.
57
- unless named_args['_bolt_api_call']
60
+ unless options[:bolt_api_call]
58
61
  executor.report_function_call(self.class.name)
59
62
  end
60
63
 
61
64
  # Report bundled content, this should capture plans run from both CLI and Plans
62
65
  executor.report_bundled_content('Plan', plan_name)
63
66
 
64
- params = named_args.reject { |k, _| k.start_with?('_') }
65
-
66
67
  loaders = closure_scope.compiler.loaders
67
68
  # The perspective of the environment is wanted here (for now) to not have to
68
69
  # require modules to have dependencies defined in meta data.
@@ -73,7 +74,7 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
73
74
  raise Bolt::Error.unknown_plan(plan_name)
74
75
  end
75
76
 
76
- if (run_as = named_args['_run_as'])
77
+ if (run_as = options[:run_as])
77
78
  old_run_as = executor.run_as
78
79
  executor.run_as = run_as
79
80
  end
@@ -118,7 +119,7 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
118
119
 
119
120
  result
120
121
  rescue Puppet::PreformattedError => e
121
- if named_args['_catch_errors'] && e.cause.is_a?(Bolt::Error)
122
+ if options[:catch_errors] && e.cause.is_a?(Bolt::Error)
122
123
  result = e.cause.to_puppet_error
123
124
  else
124
125
  raise e
@@ -43,18 +43,20 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
43
43
  return_type 'ResultSet'
44
44
  end
45
45
 
46
- def run_script(scope, script, targets, options = nil)
46
+ def run_script(scope, script, targets, options = {})
47
47
  run_script_with_description(scope, script, targets, nil, options)
48
48
  end
49
49
 
50
- def run_script_with_description(scope, script, targets, description = nil, options = nil)
50
+ def run_script_with_description(scope, script, targets, description = nil, options = {})
51
51
  unless Puppet[:tasks]
52
52
  raise Puppet::ParseErrorWithIssue
53
53
  .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_script')
54
54
  end
55
55
 
56
- options ||= {}
57
- options = options.merge('_description' => description) if description
56
+ arguments = options['arguments'] || []
57
+ options = options.select { |opt| opt.start_with?('_') }.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
58
+ options[:description] = description if description
59
+
58
60
  executor = Puppet.lookup(:bolt_executor)
59
61
  inventory = Puppet.lookup(:bolt_inventory)
60
62
 
@@ -78,10 +80,10 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
78
80
  r = if targets.empty?
79
81
  Bolt::ResultSet.new([])
80
82
  else
81
- executor.run_script(targets, found, options['arguments'] || [], options.reject { |k, _| k == 'arguments' })
83
+ executor.run_script(targets, found, arguments, options)
82
84
  end
83
85
 
84
- if !r.ok && !options['_catch_errors']
86
+ if !r.ok && !options[:catch_errors]
85
87
  raise Bolt::RunFailure.new(r, 'run_script', script)
86
88
  end
87
89
  r
@@ -12,14 +12,14 @@ Puppet::Functions.create_function(:run_task) do
12
12
  # Run a task.
13
13
  # @param task_name The task to run.
14
14
  # @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
15
- # @param task_args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
15
+ # @param args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
16
16
  # @return A list of results, one entry per target.
17
17
  # @example Run a task as root
18
18
  # run_task('facts', $targets, '_run_as' => 'root')
19
19
  dispatch :run_task do
20
20
  param 'String[1]', :task_name
21
21
  param 'Boltlib::TargetSpec', :targets
22
- optional_param 'Hash[String[1], Any]', :task_args
22
+ optional_param 'Hash[String[1], Any]', :args
23
23
  return_type 'ResultSet'
24
24
  end
25
25
 
@@ -27,7 +27,7 @@ Puppet::Functions.create_function(:run_task) do
27
27
  # @param task_name The task to run.
28
28
  # @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
29
29
  # @param description A description to be output when calling this function.
30
- # @param task_args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
30
+ # @param args Arguments to the plan. Can also include additional options: '_catch_errors', '_run_as'.
31
31
  # @return A list of results, one entry per target.
32
32
  # @example Run a task
33
33
  # run_task('facts', $targets, 'Gather OS facts')
@@ -35,27 +35,29 @@ Puppet::Functions.create_function(:run_task) do
35
35
  param 'String[1]', :task_name
36
36
  param 'Boltlib::TargetSpec', :targets
37
37
  param 'Optional[String]', :description
38
- optional_param 'Hash[String[1], Any]', :task_args
38
+ optional_param 'Hash[String[1], Any]', :args
39
39
  return_type 'ResultSet'
40
40
  end
41
41
 
42
- def run_task(task_name, targets, task_args = nil)
43
- run_task_with_description(task_name, targets, nil, task_args)
42
+ def run_task(task_name, targets, args = {})
43
+ run_task_with_description(task_name, targets, nil, args)
44
44
  end
45
45
 
46
- def run_task_with_description(task_name, targets, description, task_args = nil)
46
+ def run_task_with_description(task_name, targets, description, args = {})
47
47
  unless Puppet[:tasks]
48
48
  raise Puppet::ParseErrorWithIssue
49
49
  .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_task')
50
50
  end
51
51
 
52
- task_args ||= {}
52
+ options, params = args.partition { |k, _v| k.start_with?('_') }.map(&:to_h)
53
+ options = options.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
54
+
53
55
  executor = Puppet.lookup(:bolt_executor)
54
56
  inventory = Puppet.lookup(:bolt_inventory)
55
57
 
56
58
  # Bolt calls this function internally to trigger tasks from the CLI. We
57
59
  # don't want to count those invocations.
58
- unless task_args['_bolt_api_call']
60
+ unless options[:bolt_api_call]
59
61
  executor.report_function_call(self.class.name)
60
62
  end
61
63
 
@@ -65,9 +67,7 @@ Puppet::Functions.create_function(:run_task) do
65
67
  # Ensure that given targets are all Target instances
66
68
  targets = inventory.get_targets(targets)
67
69
 
68
- options, use_args = task_args.partition { |k, _| k.start_with?('_') }.map(&:to_h)
69
-
70
- options['_description'] = description if description
70
+ options[:description] = description if description
71
71
 
72
72
  # Don't bother loading the local task definition if all targets use the 'pcp' transport.
73
73
  if !targets.empty? && targets.all? { |t| t.transport == 'pcp' }
@@ -80,37 +80,37 @@ Puppet::Functions.create_function(:run_task) do
80
80
  raise Bolt::Error.unknown_task(task_name)
81
81
  end
82
82
 
83
- task_signature.runnable_with?(use_args) do |mismatch_message|
83
+ task_signature.runnable_with?(params) do |mismatch_message|
84
84
  raise with_stack(:TYPE_MISMATCH, mismatch_message)
85
85
  end || (raise with_stack(:TYPE_MISMATCH, 'Task parameters do not match'))
86
86
 
87
87
  task = Bolt::Task.new(task_signature.task_hash)
88
88
  end
89
89
 
90
- unless Puppet::Pops::Types::TypeFactory.data.instance?(use_args)
90
+ unless Puppet::Pops::Types::TypeFactory.data.instance?(params)
91
91
  # generate a helpful error message about the type-mismatch between the type Data
92
- # and the actual type of use_args
93
- use_args_t = Puppet::Pops::Types::TypeCalculator.infer_set(use_args)
92
+ # and the actual type of params
93
+ params_t = Puppet::Pops::Types::TypeCalculator.infer_set(params)
94
94
  desc = Puppet::Pops::Types::TypeMismatchDescriber.singleton.describe_mismatch(
95
95
  'Task parameters are not of type Data. run_task()',
96
- Puppet::Pops::Types::TypeFactory.data, use_args_t
96
+ Puppet::Pops::Types::TypeFactory.data, params_t
97
97
  )
98
98
  raise with_stack(:TYPE_NOT_DATA, desc)
99
99
  end
100
100
 
101
101
  # Wrap parameters marked with '"sensitive": true' in the task metadata with a
102
102
  # Sensitive wrapper type. This way it's not shown in logs.
103
- if (params = task.parameters)
104
- use_args.each do |k, v|
105
- if params[k] && params[k]['sensitive']
106
- use_args[k] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(v)
103
+ if (param_spec = task.parameters)
104
+ params.each do |k, v|
105
+ if param_spec[k] && param_spec[k]['sensitive']
106
+ params[k] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(v)
107
107
  end
108
108
  end
109
109
  end
110
110
 
111
111
  if executor.noop
112
112
  if task.supports_noop
113
- use_args['_noop'] = true
113
+ params['_noop'] = true
114
114
  else
115
115
  raise with_stack(:TASK_NO_NOOP, 'Task does not support noop')
116
116
  end
@@ -119,8 +119,8 @@ Puppet::Functions.create_function(:run_task) do
119
119
  if targets.empty?
120
120
  Bolt::ResultSet.new([])
121
121
  else
122
- result = executor.run_task(targets, task, use_args, options)
123
- if !result.ok && !task_args['_catch_errors']
122
+ result = executor.run_task(targets, task, params, options)
123
+ if !result.ok && !options[:catch_errors]
124
124
  raise Bolt::RunFailure.new(result, 'run_task', task_name)
125
125
  end
126
126
  result
@@ -47,18 +47,19 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct
47
47
  return_type 'ResultSet'
48
48
  end
49
49
 
50
- def upload_file(scope, source, destination, targets, options = nil)
50
+ def upload_file(scope, source, destination, targets, options = {})
51
51
  upload_file_with_description(scope, source, destination, targets, nil, options)
52
52
  end
53
53
 
54
- def upload_file_with_description(scope, source, destination, targets, description = nil, options = nil)
54
+ def upload_file_with_description(scope, source, destination, targets, description = nil, options = {})
55
55
  unless Puppet[:tasks]
56
56
  raise Puppet::ParseErrorWithIssue
57
57
  .from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'upload_file')
58
58
  end
59
59
 
60
- options ||= {}
61
- options = options.merge('_description' => description) if description
60
+ options = options.select { |opt| opt.start_with?('_') }.map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
61
+ options[:description] = description if description
62
+
62
63
  executor = Puppet.lookup(:bolt_executor)
63
64
  inventory = Puppet.lookup(:bolt_inventory)
64
65
 
@@ -80,7 +81,7 @@ Puppet::Functions.create_function(:upload_file, Puppet::Functions::InternalFunct
80
81
  r = executor.upload_file(targets, found, destination, options)
81
82
  end
82
83
 
83
- if !r.ok && !options['_catch_errors']
84
+ if !r.ok && !options[:catch_errors]
84
85
  raise Bolt::RunFailure.new(r, 'upload_file', source)
85
86
  end
86
87
  r
@@ -81,7 +81,7 @@ module Bolt
81
81
  end
82
82
 
83
83
  def compile(target, ast, plan_vars)
84
- trusted = Puppet::Context::TrustedInformation.new('local', target.host, {})
84
+ trusted = Puppet::Context::TrustedInformation.new('local', target.name, {})
85
85
  facts = @inventory.facts(target).merge('bolt' => true)
86
86
 
87
87
  catalog_input = {
@@ -90,7 +90,7 @@ module Bolt
90
90
  pdb_config: @pdb_client.config.to_hash,
91
91
  hiera_config: @hiera_config,
92
92
  target: {
93
- name: target.host,
93
+ name: target.name,
94
94
  facts: facts,
95
95
  variables: @inventory.vars(target).merge(plan_vars),
96
96
  trusted: trusted.to_h
@@ -150,7 +150,7 @@ module Bolt
150
150
  if args.count > 1
151
151
  type1 = Puppet.lookup(:pal_script_compiler).type('Hash[String, Data]')
152
152
  Puppet::Pal.assert_type(type1, args[1], 'apply options')
153
- options = args[1]
153
+ options = args[1].map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
154
154
  end
155
155
 
156
156
  # collect plan vars and merge them over target vars
@@ -196,7 +196,7 @@ module Bolt
196
196
  'catalog' => Puppet::Pops::Types::PSensitiveType::Sensitive.new(catalog),
197
197
  'plugins' => Puppet::Pops::Types::PSensitiveType::Sensitive.new(plugins),
198
198
  '_task' => catalog_apply_task.name,
199
- '_noop' => options['_noop']
199
+ '_noop' => options[:noop]
200
200
  }
201
201
 
202
202
  callback = proc do |event|
@@ -206,7 +206,8 @@ module Bolt
206
206
  @executor.publish_event(event)
207
207
  end
208
208
  # Respect the run_as default set on the executor
209
- options = { '_run_as' => @executor.run_as }.merge(options) if @executor.run_as
209
+ options[:run_as] = @executor.run_as if @executor.run_as && !options.key?(:run_as)
210
+
210
211
  results = transport.batch_task(batch, catalog_apply_task, arguments, options, &callback)
211
212
  Array(results).map { |result| ApplyResult.from_task_result(result) }
212
213
  end
@@ -220,7 +221,7 @@ module Bolt
220
221
  resource_counts = r.ok_set.map { |result| result.event_metrics&.fetch('total') }.compact
221
222
  @executor.report_apply(count_statements(raw_ast), resource_counts)
222
223
 
223
- if !r.ok && !options['_catch_errors']
224
+ if !r.ok && !options[:catch_errors]
224
225
  raise Bolt::ApplyFailure, r
225
226
  end
226
227
  r
@@ -341,7 +341,7 @@ module Bolt
341
341
 
342
342
  elapsed_time = Benchmark.realtime do
343
343
  executor_opts = {}
344
- executor_opts['_description'] = options[:description] if options.key?(:description)
344
+ executor_opts[:description] = options[:description] if options.key?(:description)
345
345
  executor.subscribe(outputter)
346
346
  executor.subscribe(log_outputter)
347
347
  results =
@@ -462,7 +462,7 @@ module Bolt
462
462
  end
463
463
 
464
464
  results = pal.with_bolt_executor(executor, inventory, puppetdb_client) do
465
- Puppet.lookup(:apply_executor).apply_ast(ast, targets, '_catch_errors' => true, '_noop' => noop)
465
+ Puppet.lookup(:apply_executor).apply_ast(ast, targets, catch_errors: true, noop: noop)
466
466
  end
467
467
  end
468
468
 
@@ -218,16 +218,16 @@ module Bolt
218
218
  end
219
219
 
220
220
  def with_node_logging(description, batch)
221
- @logger.info("#{description} on #{batch.map(&:uri)}")
221
+ @logger.info("#{description} on #{batch.map(&:safe_name)}")
222
222
  result = yield
223
223
  @logger.info(result.to_json)
224
224
  result
225
225
  end
226
226
 
227
227
  def run_command(targets, command, options = {})
228
- description = options.fetch('_description', "command '#{command}'")
228
+ description = options.fetch(:description, "command '#{command}'")
229
229
  log_action(description, targets) do
230
- options = { '_run_as' => run_as }.merge(options) if run_as
230
+ options[:run_as] = run_as if run_as && !options.key?(:run_as)
231
231
 
232
232
  batch_execute(targets) do |transport, batch|
233
233
  with_node_logging("Running command '#{command}'", batch) do
@@ -238,9 +238,9 @@ module Bolt
238
238
  end
239
239
 
240
240
  def run_script(targets, script, arguments, options = {})
241
- description = options.fetch('_description', "script #{script}")
241
+ description = options.fetch(:description, "script #{script}")
242
242
  log_action(description, targets) do
243
- options = { '_run_as' => run_as }.merge(options) if run_as
243
+ options[:run_as] = run_as if run_as && !options.key?(:run_as)
244
244
 
245
245
  batch_execute(targets) do |transport, batch|
246
246
  with_node_logging("Running script #{script} with '#{arguments.to_json}'", batch) do
@@ -251,9 +251,9 @@ module Bolt
251
251
  end
252
252
 
253
253
  def run_task(targets, task, arguments, options = {})
254
- description = options.fetch('_description', "task #{task.name}")
254
+ description = options.fetch(:description, "task #{task.name}")
255
255
  log_action(description, targets) do
256
- options = { '_run_as' => run_as }.merge(options) if run_as
256
+ options[:run_as] = run_as if run_as && !options.key?(:run_as)
257
257
  arguments['_task'] = task.name
258
258
 
259
259
  batch_execute(targets) do |transport, batch|
@@ -265,9 +265,9 @@ module Bolt
265
265
  end
266
266
 
267
267
  def upload_file(targets, source, destination, options = {})
268
- description = options.fetch('_description', "file upload from #{source} to #{destination}")
268
+ description = options.fetch(:description, "file upload from #{source} to #{destination}")
269
269
  log_action(description, targets) do
270
- options = { '_run_as' => run_as }.merge(options) if run_as
270
+ options[:run_as] = run_as if run_as && !options.key?(:run_as)
271
271
 
272
272
  batch_execute(targets) do |transport, batch|
273
273
  with_node_logging("Uploading file #{source} to #{destination}", batch) do
@@ -73,14 +73,14 @@ module Bolt
73
73
  end
74
74
 
75
75
  def print_start(target)
76
- @stream.puts(colorize(:green, "Started on #{target.host}..."))
76
+ @stream.puts(colorize(:green, "Started on #{target.safe_name}..."))
77
77
  end
78
78
 
79
79
  def print_result(result)
80
80
  if result.success?
81
- @stream.puts(colorize(:green, "Finished on #{result.target.host}:"))
81
+ @stream.puts(colorize(:green, "Finished on #{result.target.safe_name}:"))
82
82
  else
83
- @stream.puts(colorize(:red, "Failed on #{result.target.host}:"))
83
+ @stream.puts(colorize(:red, "Failed on #{result.target.safe_name}:"))
84
84
  end
85
85
 
86
86
  if result.error_hash
@@ -170,7 +170,7 @@ module Bolt
170
170
  @stream.puts format('Successful on %<size>d node%<plural>s: %<names>s',
171
171
  size: ok_set.size,
172
172
  plural: ok_set.size == 1 ? '' : 's',
173
- names: ok_set.names.join(','))
173
+ names: ok_set.targets.map(&:safe_name).join(','))
174
174
  end
175
175
 
176
176
  error_set = results.error_set
@@ -179,7 +179,7 @@ module Bolt
179
179
  format('Failed on %<size>d node%<plural>s: %<names>s',
180
180
  size: error_set.size,
181
181
  plural: error_set.size == 1 ? '' : 's',
182
- names: error_set.names.join(',')))
182
+ names: error_set.targets.map(&:safe_name).join(',')))
183
183
  end
184
184
 
185
185
  total_msg = format('Ran on %<size>d node%<plural>s',
@@ -143,11 +143,12 @@ module Bolt
143
143
  @analytics = analytics
144
144
  @plugin_context = PluginContext.new(config, pal)
145
145
  @plugins = {}
146
+ @pal = pal
146
147
  @unknown = Set.new
147
148
  end
148
149
 
149
150
  def modules
150
- @modules ||= Bolt::Module.discover(@config.modulepath)
151
+ @modules ||= Bolt::Module.discover(@pal.modulepath)
151
152
  end
152
153
 
153
154
  # Generally this is private. Puppetdb is special though
@@ -164,7 +164,7 @@ module Bolt
164
164
  params = params.merge(metaparams)
165
165
 
166
166
  # There are no executor options to pass now.
167
- options = { "_catch_errors" => true }
167
+ options = { catch_errors: true }
168
168
 
169
169
  result = @context.run_local_task(task,
170
170
  params,
@@ -39,7 +39,7 @@ module Bolt
39
39
 
40
40
  def private_key_path
41
41
  path = @options['private-key'] || 'keys/private_key.pkcs7.pem'
42
- path = File.absolute_path(path, boltdir)
42
+ path = File.expand_path(path, boltdir)
43
43
  @logger.debug("Using private-key: #{path}")
44
44
  path
45
45
  end
@@ -50,7 +50,7 @@ module Bolt
50
50
 
51
51
  def public_key_path
52
52
  path = @options['public-key'] || 'keys/public_key.pkcs7.pem'
53
- path = File.absolute_path(path, boltdir)
53
+ path = File.expand_path(path, boltdir)
54
54
  @logger.debug("Using public-key: #{path}")
55
55
  path
56
56
  end
@@ -19,7 +19,7 @@ module Bolt
19
19
 
20
20
  def run_task(opts)
21
21
  params = opts['parameters'] || {}
22
- options = { '_catch_errors' => true }
22
+ options = { catch_errors: true }
23
23
 
24
24
  raise Bolt::ValidationError, "Task plugin requires that the 'task' is specified" unless opts['task']
25
25
  task = @context.get_validated_task(opts['task'], params)
@@ -106,5 +106,13 @@ module Bolt
106
106
  def ==(other)
107
107
  eql?(other)
108
108
  end
109
+
110
+ def [](from, up_to = nil)
111
+ if up_to
112
+ @results[from..up_to]
113
+ else
114
+ @results[from]
115
+ end
116
+ end
109
117
  end
110
118
  end
@@ -147,6 +147,11 @@ module Bolt
147
147
  Addressable::URI.unencode_component(component)
148
148
  end
149
149
  private :unencode
150
+
151
+ def eql?(other)
152
+ self.class.equal?(other.class) && @name == other.name
153
+ end
154
+ alias == eql?
150
155
  end
151
156
 
152
157
  class Target
@@ -247,13 +252,10 @@ module Bolt
247
252
  # should we just compare names? is there something else that is meaninful?
248
253
  def eql?(other)
249
254
  if self.class.equal?(other.class)
250
- if @uri
251
- return @uri == other.uri
252
- else
253
- @name = other.name
254
- end
255
+ @uri ? @uri == other.uri : @name == other.name
256
+ else
257
+ false
255
258
  end
256
- false
257
259
  end
258
260
  alias == eql?
259
261
 
@@ -281,6 +283,7 @@ module Bolt
281
283
  def host
282
284
  @uri_obj&.hostname || @host
283
285
  end
286
+ alias safe_name host
284
287
 
285
288
  def name
286
289
  @name || @uri
@@ -44,7 +44,7 @@ module Bolt
44
44
  else
45
45
  result = executor.run_task(targets, task, params, options)
46
46
 
47
- if !result.ok && !options['_catch_errors']
47
+ if !result.ok && !options[:catch_errors]
48
48
  raise Bolt::RunFailure.new(result, 'run_task', task.name)
49
49
  end
50
50
  result
@@ -125,7 +125,7 @@ module Bolt
125
125
  assert_batch_size_one("batch_task()", targets)
126
126
  target = targets.first
127
127
  with_events(target, callback) do
128
- @logger.debug { "Running task run '#{task}' on #{target.uri}" }
128
+ @logger.debug { "Running task run '#{task}' on #{target.safe_name}" }
129
129
  run_task(target, task, arguments, options)
130
130
  end
131
131
  end
@@ -139,7 +139,7 @@ module Bolt
139
139
  assert_batch_size_one("batch_command()", targets)
140
140
  target = targets.first
141
141
  with_events(target, callback) do
142
- @logger.debug("Running command '#{command}' on #{target.uri}")
142
+ @logger.debug("Running command '#{command}' on #{target.safe_name}")
143
143
  run_command(target, command, options)
144
144
  end
145
145
  end
@@ -153,7 +153,7 @@ module Bolt
153
153
  assert_batch_size_one("batch_script()", targets)
154
154
  target = targets.first
155
155
  with_events(target, callback) do
156
- @logger.debug { "Running script '#{script}' on #{target.uri}" }
156
+ @logger.debug { "Running script '#{script}' on #{target.safe_name}" }
157
157
  run_script(target, script, arguments, options)
158
158
  end
159
159
  end
@@ -167,7 +167,7 @@ module Bolt
167
167
  assert_batch_size_one("batch_upload()", targets)
168
168
  target = targets.first
169
169
  with_events(target, callback) do
170
- @logger.debug { "Uploading: '#{source}' to #{destination} on #{target.uri}" }
170
+ @logger.debug { "Uploading: '#{source}' to #{destination} on #{target.safe_name}" }
171
171
  upload(target, source, destination, options)
172
172
  end
173
173
  end
@@ -8,9 +8,9 @@ module Bolt
8
8
  class Docker < Base
9
9
  class Connection
10
10
  def initialize(target)
11
- raise Bolt::ValidationError, "Target #{target.name} does not have a host" unless target.host
11
+ raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host
12
12
  @target = target
13
- @logger = Logging.logger[target.host]
13
+ @logger = Logging.logger[target.safe_name]
14
14
  @docker_host = @target.options['service-url']
15
15
  end
16
16
 
@@ -28,7 +28,7 @@ module Bolt
28
28
  true
29
29
  rescue StandardError => e
30
30
  raise Bolt::Node::ConnectError.new(
31
- "Failed to connect to #{@target.uri}: #{e.message}",
31
+ "Failed to connect to #{@target.safe_name}: #{e.message}",
32
32
  'CONNECT_ERROR'
33
33
  )
34
34
  end
@@ -79,6 +79,7 @@ module Bolt
79
79
  end
80
80
 
81
81
  def write_remote_file(source, destination)
82
+ @logger.debug { "Uploading #{source}, to #{destination}" }
82
83
  _, stdout_str, status = execute_local_docker_command('cp', [source, "#{container_id}:#{destination}"])
83
84
  raise "Error writing file to container #{@container_id}: #{stdout_str}" unless status.exitstatus.zero?
84
85
  rescue StandardError => e
@@ -86,6 +87,7 @@ module Bolt
86
87
  end
87
88
 
88
89
  def write_remote_directory(source, destination)
90
+ @logger.debug { "Uploading #{source}, to #{destination}" }
89
91
  _, stdout_str, status = execute_local_docker_command('cp', [source, "#{container_id}:#{destination}"])
90
92
  raise "Error writing directory to container #{@container_id}: #{stdout_str}" unless status.exitstatus.zero?
91
93
  rescue StandardError => e
@@ -73,6 +73,7 @@ module Bolt
73
73
  end
74
74
 
75
75
  def copy_file(source, dest)
76
+ @logger.debug { "Uploading #{source}, to #{dest}" }
76
77
  if source.is_a?(StringIO)
77
78
  File.open("tempfile", "w") { |f| f.write(source.read) }
78
79
  execute(['mv', 'tempfile', dest])
@@ -27,7 +27,7 @@ module Bolt
27
27
 
28
28
  def self.validate(options)
29
29
  logger = Logging.logger[self]
30
- if options['sudo-password'] || options['run-as'] || options['run-as-command'] || options['_run_as']
30
+ if options['sudo-password'] || options['run-as'] || options['run-as-command'] || options[:run_as]
31
31
  logger.warn("run-as is not supported for Windows hosts using the local transport")
32
32
  end
33
33
  end
@@ -47,6 +47,7 @@ module Bolt
47
47
  private :in_tmpdir
48
48
 
49
49
  def copy_file(source, destination)
50
+ logger.debug { "Uploading #{source}, to #{destination}" }
50
51
  FileUtils.cp_r(source, destination, remove_destination: true)
51
52
  rescue StandardError => e
52
53
  raise Bolt::Node::FileError.new(e.message, 'WRITE_ERROR')
@@ -81,7 +81,7 @@ module Bolt
81
81
  target,
82
82
  value: { '_error' => {
83
83
  'kind' => 'puppetlabs.tasks/skipped-node',
84
- 'msg' => "Node #{target.host} was skipped",
84
+ 'msg' => "Node #{target.safe_name} was skipped",
85
85
  'details' => {}
86
86
  } },
87
87
  action: 'task', object: task_name
@@ -78,7 +78,7 @@ module Bolt
78
78
  end
79
79
 
80
80
  def run_task(targets, task, arguments, options)
81
- body = build_request(targets, task, arguments, options['_description'])
81
+ body = build_request(targets, task, arguments, options[:description])
82
82
  @client.run_task(body)
83
83
  end
84
84
 
@@ -73,7 +73,7 @@ module Bolt
73
73
  begin
74
74
  conn&.disconnect
75
75
  rescue StandardError => e
76
- logger.info("Failed to close connection to #{target.uri} : #{e.message}")
76
+ logger.info("Failed to close connection to #{target.safe_name} : #{e.message}")
77
77
  end
78
78
  end
79
79
 
@@ -19,7 +19,7 @@ module Bolt
19
19
  require 'net/ssh'
20
20
  require 'net/ssh/proxy/jump'
21
21
 
22
- raise Bolt::ValidationError, "Target #{target.name} does not have a host" unless target.host
22
+ raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host
23
23
  @sudo_id = SecureRandom.uuid
24
24
 
25
25
  @target = target
@@ -30,7 +30,7 @@ module Bolt
30
30
  @run_as = nil
31
31
  @strict_host_key_checking = ssh_config[:strict_host_key_checking]
32
32
 
33
- @logger = Logging.logger[@target.host]
33
+ @logger = Logging.logger[@target.safe_name]
34
34
  @transport_logger = transport_logger
35
35
 
36
36
  if target.options['private-key']&.instance_of?(String)
@@ -119,17 +119,17 @@ module Bolt
119
119
  )
120
120
  rescue Net::SSH::HostKeyError => e
121
121
  raise Bolt::Node::ConnectError.new(
122
- "Host key verification failed for #{target.uri}: #{e.message}",
122
+ "Host key verification failed for #{target.safe_name}: #{e.message}",
123
123
  'HOST_KEY_ERROR'
124
124
  )
125
125
  rescue Net::SSH::ConnectionTimeout
126
126
  raise Bolt::Node::ConnectError.new(
127
- "Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.uri}",
127
+ "Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.safe_name}",
128
128
  'CONNECT_ERROR'
129
129
  )
130
130
  rescue StandardError => e
131
131
  raise Bolt::Node::ConnectError.new(
132
- "Failed to connect to #{target.uri}: #{e.message}",
132
+ "Failed to connect to #{target.safe_name}: #{e.message}",
133
133
  'CONNECT_ERROR'
134
134
  )
135
135
  end
@@ -155,7 +155,7 @@ module Bolt
155
155
  # Cancel the sudo prompt to prevent later commands getting stuck
156
156
  channel.close
157
157
  raise Bolt::Node::EscalateError.new(
158
- "Sudo password for user #{@user} was not provided for #{target.uri}",
158
+ "Sudo password for user #{@user} was not provided for #{target.safe_name}",
159
159
  'NO_PASSWORD'
160
160
  )
161
161
  end
@@ -168,13 +168,13 @@ module Bolt
168
168
  elsif data =~ /^#{@user} is not in the sudoers file\./
169
169
  @logger.debug { data }
170
170
  raise Bolt::Node::EscalateError.new(
171
- "User #{@user} does not have sudo permission on #{target.uri}",
171
+ "User #{@user} does not have sudo permission on #{target.safe_name}",
172
172
  'SUDO_DENIED'
173
173
  )
174
174
  elsif data =~ /^Sorry, try again\./
175
175
  @logger.debug { data }
176
176
  raise Bolt::Node::EscalateError.new(
177
- "Sudo password for user #{@user} not recognized on #{target.uri}",
177
+ "Sudo password for user #{@user} not recognized on #{target.safe_name}",
178
178
  'BAD_PASSWORD'
179
179
  )
180
180
  end
@@ -261,18 +261,13 @@ module Bolt
261
261
  end
262
262
 
263
263
  def copy_file(source, destination)
264
+ # Do not log wrapper script content
265
+ @logger.debug { "Uploading #{source}, to #{destination}" } unless source.is_a?(StringIO)
264
266
  @session.scp.upload!(source, destination, recursive: true)
265
267
  rescue StandardError => e
266
268
  raise Bolt::Node::FileError.new(e.message, 'WRITE_ERROR')
267
269
  end
268
270
 
269
- def write_executable_from_content(dest, content, filename)
270
- remote_path = File.join(dest.to_s, filename)
271
- @session.scp.upload!(StringIO.new(content), remote_path)
272
- make_executable(remote_path)
273
- remote_path
274
- end
275
-
276
271
  # This handles renaming Net::SSH verifiers between version 4.x and 5.x
277
272
  # of the gem
278
273
  def net_ssh_verifier(verifier)
@@ -19,7 +19,7 @@ module Bolt
19
19
 
20
20
  def run_command(target, command, options = {})
21
21
  with_connection(target) do |conn|
22
- conn.running_as(options['_run_as']) do
22
+ conn.running_as(options[:run_as]) do
23
23
  output = conn.execute(command, sudoable: true)
24
24
  Bolt::Result.for_command(target,
25
25
  output.stdout.string,
@@ -32,7 +32,7 @@ module Bolt
32
32
 
33
33
  def upload(target, source, destination, options = {})
34
34
  with_connection(target) do |conn|
35
- conn.running_as(options['_run_as']) do
35
+ conn.running_as(options[:run_as]) do
36
36
  conn.with_tempdir do |dir|
37
37
  basename = File.basename(destination)
38
38
  tmpfile = File.join(dir.to_s, basename)
@@ -55,7 +55,7 @@ module Bolt
55
55
  arguments = unwrap_sensitive_args(arguments)
56
56
 
57
57
  with_connection(target) do |conn|
58
- conn.running_as(options['_run_as']) do
58
+ conn.running_as(options[:run_as]) do
59
59
  conn.with_tempdir do |dir|
60
60
  path = conn.write_executable(dir.to_s, script)
61
61
  dir.chown(conn.run_as)
@@ -77,7 +77,7 @@ module Bolt
77
77
  extra_files = implementation['files']
78
78
 
79
79
  with_connection(target) do |conn|
80
- conn.running_as(options['_run_as']) do
80
+ conn.running_as(options[:run_as]) do
81
81
  stdin, output = nil
82
82
  execute_options = {}
83
83
  execute_options[:interpreter] = select_interpreter(executable, target.options['interpreters'])
@@ -10,7 +10,7 @@ module Bolt
10
10
  def initialize(target)
11
11
  @target = target
12
12
  @run_as = nil
13
- @logger = Logging.logger[@target.host]
13
+ @logger = Logging.logger[@target.safe_name]
14
14
  end
15
15
 
16
16
  # This method allows the @run_as variable to be used as a per-operation
@@ -75,7 +75,7 @@ module Bolt
75
75
  begin
76
76
  conn&.disconnect
77
77
  rescue StandardError => e
78
- logger.info("Failed to close connection to #{target.uri} : #{e.message}")
78
+ logger.info("Failed to close connection to #{target.safe_name} : #{e.message}")
79
79
  end
80
80
  end
81
81
 
@@ -12,7 +12,7 @@ module Bolt
12
12
  DEFAULT_EXTENSIONS = ['.ps1', '.rb', '.pp'].freeze
13
13
 
14
14
  def initialize(target, transport_logger)
15
- raise Bolt::ValidationError, "Target #{target.name} does not have a host" unless target.host
15
+ raise Bolt::ValidationError, "Target #{target.safe_name} does not have a host" unless target.host
16
16
  @target = target
17
17
 
18
18
  default_port = target.options['ssl'] ? HTTPS_PORT : HTTP_PORT
@@ -23,7 +23,7 @@ module Bolt
23
23
  extensions += target.options['interpreters'].keys if target.options['interpreters']
24
24
  @extensions = DEFAULT_EXTENSIONS.to_set.merge(extensions)
25
25
 
26
- @logger = Logging.logger[@target.host]
26
+ @logger = Logging.logger[@target.safe_name]
27
27
  @transport_logger = transport_logger
28
28
  end
29
29
 
@@ -148,6 +148,7 @@ module Bolt
148
148
  end
149
149
 
150
150
  def write_remote_file(source, destination)
151
+ @logger.debug { "Uploading #{source}, to #{destination}" }
151
152
  if target.options['file-protocol'] == 'smb'
152
153
  write_remote_file_smb(source, destination)
153
154
  else
@@ -223,13 +224,6 @@ module Bolt
223
224
  remote_path
224
225
  end
225
226
 
226
- def write_executable_from_content(dir, content, filename)
227
- validate_extensions(File.extname(filename))
228
- remote_path = "#{dir}\\#{filename}"
229
- write_remote_file(content, remote_path)
230
- remote_path
231
- end
232
-
233
227
  private
234
228
 
235
229
  def smb_client_login
@@ -243,12 +237,12 @@ module Bolt
243
237
  @logger.debug { "Connected to #{@client.dns_host_name}" }
244
238
  when WindowsError::NTStatus::STATUS_LOGON_FAILURE
245
239
  raise Bolt::Node::ConnectError.new(
246
- "SMB authentication failed for #{target.host}",
240
+ "SMB authentication failed for #{target.safe_name}",
247
241
  'AUTH_ERROR'
248
242
  )
249
243
  else
250
244
  raise Bolt::Node::ConnectError.new(
251
- "Failed to connect to #{target.host} using SMB: #{status.description}",
245
+ "Failed to connect to #{target.safe_name} using SMB: #{status.description}",
252
246
  'CONNECT_ERROR'
253
247
  )
254
248
  end
@@ -267,12 +261,12 @@ module Bolt
267
261
  rescue Errno::ECONNREFUSED => e
268
262
  # handle this to prevent obscuring error message as SMB problem
269
263
  raise Bolt::Node::ConnectError.new(
270
- "Failed to connect to #{target.host} using SMB: #{e.message}",
264
+ "Failed to connect to #{target.safe_name} using SMB: #{e.message}",
271
265
  'CONNECT_ERROR'
272
266
  )
273
267
  rescue Timeout::Error
274
268
  raise Bolt::Node::ConnectError.new(
275
- "Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.host}",
269
+ "Timeout after #{target.options['connect-timeout']} seconds connecting to #{target.safe_name}",
276
270
  'CONNECT_ERROR'
277
271
  )
278
272
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '1.32.0'
4
+ VERSION = '1.33.0'
5
5
  end
@@ -35,7 +35,8 @@ module BoltSpec
35
35
  # Public methods
36
36
 
37
37
  def with_params(params)
38
- @invocation[:options] = params
38
+ @invocation[:options] = params.select { |k, _v| k.start_with?('_') }
39
+ .map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
39
40
  self
40
41
  end
41
42
  end
@@ -44,6 +44,7 @@ module BoltSpec
44
44
  @invocation[:params] = params
45
45
  @invocation[:arguments] = params['arguments']
46
46
  @invocation[:options] = params.select { |k, _v| k.start_with?('_') }
47
+ .map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
47
48
  self
48
49
  end
49
50
  end
@@ -46,6 +46,7 @@ module BoltSpec
46
46
  @invocation[:params] = params
47
47
  @invocation[:arguments] = params.reject { |k, _v| k.start_with?('_') }
48
48
  @invocation[:options] = params.select { |k, _v| k.start_with?('_') }
49
+ .map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
49
50
  self
50
51
  end
51
52
  end
@@ -56,7 +56,8 @@ module BoltSpec
56
56
  end
57
57
 
58
58
  def with_params(params)
59
- @invocation[:options] = params
59
+ @invocation[:options] = params.select { |k, _v| k.start_with?('_') }
60
+ .map { |k, v| [k.sub(/^_/, '').to_sym, v] }.to_h
60
61
  self
61
62
  end
62
63
  end
@@ -202,7 +202,7 @@ module BoltSpec
202
202
  end
203
203
 
204
204
  pal.with_bolt_executor(executor, inventory, puppetdb_client) do
205
- Puppet.lookup(:apply_executor).apply_ast(ast, targets, '_catch_errors' => true, '_noop' => noop)
205
+ Puppet.lookup(:apply_executor).apply_ast(ast, targets, catch_errors: true, noop: noop)
206
206
  end
207
207
  end
208
208
  end
@@ -79,7 +79,7 @@ module PlanExecutor
79
79
  end
80
80
 
81
81
  def run_command(targets, command, options = {})
82
- description = options.fetch('_description', "command '#{command}'")
82
+ description = options.fetch(:description, "command '#{command}'")
83
83
  log_action(description, targets) do
84
84
  results = as_resultset(targets) do
85
85
  @orch_client.run_command(targets, command, options)
@@ -90,7 +90,7 @@ module PlanExecutor
90
90
  end
91
91
 
92
92
  def run_script(targets, script, arguments, options = {})
93
- description = options.fetch('_description', "script #{script}")
93
+ description = options.fetch(:description, "script #{script}")
94
94
  log_action(description, targets) do
95
95
  results = as_resultset(targets) do
96
96
  @orch_client.run_script(targets, script, arguments, options)
@@ -101,7 +101,7 @@ module PlanExecutor
101
101
  end
102
102
 
103
103
  def run_task(targets, task, arguments, options = {})
104
- description = options.fetch('_description', "task #{task.name}")
104
+ description = options.fetch(:description, "task #{task.name}")
105
105
  log_action(description, targets) do
106
106
  arguments['_task'] = task.name
107
107
 
@@ -114,7 +114,7 @@ module PlanExecutor
114
114
  end
115
115
 
116
116
  def upload_file(targets, source, destination, options = {})
117
- description = options.fetch('_description', "file upload from #{source} to #{destination}")
117
+ description = options.fetch(:description, "file upload from #{source} to #{destination}")
118
118
  log_action(description, targets) do
119
119
  results = as_resultset(targets) do
120
120
  @orch_client.file_upload(targets, source, destination, options)
@@ -61,7 +61,7 @@ module PlanExecutor
61
61
  end
62
62
 
63
63
  def send_request(targets, task, arguments, options = {})
64
- description = options['_description']
64
+ description = options[:description]
65
65
  body = { task: task.name,
66
66
  environment: @environment,
67
67
  noop: arguments['_noop'],
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: 1.32.0
4
+ version: 1.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-03 00:00:00.000000000 Z
11
+ date: 2019-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable