bolt 0.18.1 → 0.18.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0658ba25967cd7fac93e3b0c410793f2d389849f
4
- data.tar.gz: f7a6cafb673449de219fb9bade1e672d4ff858eb
3
+ metadata.gz: 5705a6c7d44fd856ef5bf240252574ddb823a336
4
+ data.tar.gz: 70027049c0bb060a5b04bd7a9ca5b00772466fc4
5
5
  SHA512:
6
- metadata.gz: 3908b25652b38dd0a7e48656b3442fe6b5e85fd23942dbb2be207f4f4f39397b18d7b87706791075773b53c0d297d0b9ba8743a0070c5bcde8d8d7be11a71ce8
7
- data.tar.gz: e837918752a7e2cc2ac2bff3aa72f480c4fcf7f498fca15cf355a9cb2b7bc24faa2e91b1684e7650ead33a06315961ceb6792148b70cff974bc0e960972454ca
6
+ metadata.gz: 032844c9618c04162ef3bfe3e4ae6eade64f952478906d6b02539d57fd6e4325d38f35ba818e6ff1fb42fa3fd2e7f01a25527666b68560038a0c479a5ec39dfd
7
+ data.tar.gz: b9df84d3b06f1d24d1c554cd5631f381356b2e0cadcbe2c2685b3b6fe610ca237611877148d5ff7f90064fc08d9925d53bfef6a0c85f0f3f5c516fc6216eb4ca
@@ -19,8 +19,24 @@ Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunct
19
19
  return_type 'ResultSet'
20
20
  end
21
21
 
22
+ dispatch :file_upload_with_description do
23
+ scope_param
24
+ param 'String[1]', :source
25
+ param 'String[1]', :destination
26
+ param 'Boltlib::TargetSpec', :targets
27
+ param 'String', :description
28
+ optional_param 'Hash[String[1], Any]', :options
29
+ return_type 'ResultSet'
30
+ end
31
+
22
32
  def file_upload(scope, source, destination, targets, options = nil)
33
+ file_upload_with_description(scope, source, destination, targets, nil, options)
34
+ end
35
+
36
+ def file_upload_with_description(scope, source, destination, targets, description = nil, options = nil)
23
37
  options ||= {}
38
+ options = options.merge('_description' => description) if description
39
+
24
40
  unless Puppet[:tasks]
25
41
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
26
42
  Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, operation: 'file_upload'
@@ -48,7 +64,7 @@ Puppet::Functions.create_function(:file_upload, Puppet::Functions::InternalFunct
48
64
  call_function('debug', "Simulating file upload of '#{found}' - no targets given - no action taken")
49
65
  r = Bolt::ResultSet.new([])
50
66
  else
51
- r = executor.file_upload(targets, found, destination, options.select { |k, _| k == '_run_as' })
67
+ r = executor.file_upload(targets, found, destination, options)
52
68
  end
53
69
 
54
70
  if !r.ok && !options['_catch_errors']
@@ -11,17 +11,28 @@ require 'bolt/error'
11
11
  #
12
12
  Puppet::Functions.create_function(:puppetdb_fact) do
13
13
  dispatch :puppetdb_fact do
14
- param 'Array[String]', :targets
14
+ param 'Array[String]', :certnames
15
+ return_type 'Hash[String, Data]'
15
16
  end
16
17
 
17
- def puppetdb_fact(targets)
18
+ def puppetdb_fact(certnames)
18
19
  unless Puppet[:tasks]
19
20
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
20
21
  Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, operation: 'puppetdb_fact'
21
22
  )
22
23
  end
23
24
 
24
- executor = Puppet.lookup(:bolt_executor) { nil }
25
- executor.puppetdb_fact(targets)
25
+ puppetdb_client = Puppet.lookup(:bolt_pdb_client) { nil }
26
+ unless puppetdb_client && Puppet.features.bolt?
27
+ raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
28
+ Puppet::Pops::Issues::TASK_MISSING_BOLT, action: _('query facts from puppetdb')
29
+ )
30
+ end
31
+
32
+ begin
33
+ puppetdb_client.facts_for_node(certnames)
34
+ rescue StandardError => e
35
+ raise Bolt::CLIError, "Could not retrieve targets from PuppetDB: #{e}"
36
+ end
26
37
  end
27
38
  end
@@ -17,8 +17,22 @@ Puppet::Functions.create_function(:run_command) do
17
17
  return_type 'ResultSet'
18
18
  end
19
19
 
20
+ dispatch :run_command_with_description do
21
+ param 'String[1]', :command
22
+ param 'Boltlib::TargetSpec', :targets
23
+ param 'String', :description
24
+ optional_param 'Hash[String[1], Any]', :options
25
+ return_type 'ResultSet'
26
+ end
27
+
20
28
  def run_command(command, targets, options = nil)
29
+ run_command_with_description(command, targets, nil, options)
30
+ end
31
+
32
+ def run_command_with_description(command, targets, description = nil, options = nil)
21
33
  options ||= {}
34
+ options = options.merge('_description' => description) if description
35
+
22
36
  unless Puppet[:tasks]
23
37
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
24
38
  Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, operation: 'run_command'
@@ -40,7 +54,7 @@ Puppet::Functions.create_function(:run_command) do
40
54
  call_function('debug', "Simulating run_command('#{command}') - no targets given - no action taken")
41
55
  r = Bolt::ResultSet.new([])
42
56
  else
43
- r = executor.run_command(targets, command, options.select { |k, _| k == '_run_as' })
57
+ r = executor.run_command(targets, command, options)
44
58
  end
45
59
 
46
60
  if !r.ok && !options['_catch_errors']
@@ -16,8 +16,23 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
16
16
  return_type 'ResultSet'
17
17
  end
18
18
 
19
+ dispatch :run_script_with_description do
20
+ scope_param
21
+ param 'String[1]', :script
22
+ param 'Boltlib::TargetSpec', :targets
23
+ param 'String', :description
24
+ optional_param 'Hash[String[1], Any]', :options
25
+ return_type 'ResultSet'
26
+ end
27
+
19
28
  def run_script(scope, script, targets, options = nil)
29
+ run_script_with_description(scope, script, targets, nil, options)
30
+ end
31
+
32
+ def run_script_with_description(scope, script, targets, description = nil, options = nil)
20
33
  options ||= {}
34
+ options = options.merge('_description' => description) if description
35
+
21
36
  unless Puppet[:tasks]
22
37
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
23
38
  Puppet::Pops::Issues::TASK_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, operation: 'run_script'
@@ -50,7 +65,7 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
50
65
  r = if targets.empty?
51
66
  Bolt::ResultSet.new([])
52
67
  else
53
- executor.run_script(targets, found, options['arguments'] || [], options.select { |k, _| k == '_run_as' })
68
+ executor.run_script(targets, found, options['arguments'] || [], options.reject { |k, _| k == 'arguments' })
54
69
  end
55
70
 
56
71
  if !r.ok && !options['_catch_errors']
@@ -10,6 +10,14 @@ require 'bolt/error'
10
10
  # * The returned value contains information about the result per target.
11
11
  #
12
12
  Puppet::Functions.create_function(:run_task) do
13
+ dispatch :run_task_with_description do
14
+ param 'String[1]', :task_name
15
+ param 'Boltlib::TargetSpec', :targets
16
+ param 'String', :description
17
+ optional_param 'Hash[String[1], Any]', :task_args
18
+ return_type 'ResultSet'
19
+ end
20
+
13
21
  dispatch :run_task do
14
22
  param 'String[1]', :task_name
15
23
  param 'Boltlib::TargetSpec', :targets
@@ -21,21 +29,26 @@ Puppet::Functions.create_function(:run_task) do
21
29
  dispatch :run_task_raw do
22
30
  param 'String[1]', :task_name
23
31
  param 'Boltlib::TargetSpec', :targets
32
+ param 'Optional[String]', :description
24
33
  optional_param 'Hash[String[1], Any]', :task_args
25
34
  # return_type 'ResultSet'
26
35
  block_param
27
36
  end
28
37
 
29
38
  def run_task(task_name, targets, task_args = nil)
39
+ run_task_with_description(task_name, targets, nil, task_args)
40
+ end
41
+
42
+ def run_task_with_description(task_name, targets, description, task_args = nil)
30
43
  task_args ||= {}
31
- r = run_task_raw(task_name, targets, task_args)
44
+ r = run_task_raw(task_name, targets, description, task_args)
32
45
  if !r.ok && !task_args['_catch_errors']
33
46
  raise Bolt::RunFailure.new(r, 'run_task', task_name)
34
47
  end
35
48
  r
36
49
  end
37
50
 
38
- def run_task_raw(task_name, targets, task_args = nil, &block)
51
+ def run_task_raw(task_name, targets, description = nil, task_args = nil, &block)
39
52
  task_args ||= {}
40
53
  unless Puppet[:tasks]
41
54
  raise Puppet::ParseErrorWithIssue.from_issue_and_stack(
@@ -54,7 +67,9 @@ Puppet::Functions.create_function(:run_task) do
54
67
  # Ensure that given targets are all Target instances
55
68
  targets = inventory.get_targets(targets)
56
69
 
57
- use_args = task_args.reject { |k, _| k.start_with?('_') }
70
+ options, use_args = task_args.partition { |k, _| k.start_with?('_') }.map(&:to_h)
71
+
72
+ options['_description'] = description if description
58
73
 
59
74
  # Don't bother loading the local task definition if all targets use the 'pcp' transport
60
75
  # and the local-validation option is set to false for all of them
@@ -94,7 +109,6 @@ Puppet::Functions.create_function(:run_task) do
94
109
  if targets.empty?
95
110
  Bolt::ResultSet.new([])
96
111
  else
97
- options = task_args.select { |k, _| k == '_run_as' }
98
112
  executor.run_task(targets, task, use_args, options, &block)
99
113
  end
100
114
  end
@@ -16,6 +16,7 @@ require 'bolt/puppetdb'
16
16
  require 'bolt/pal'
17
17
  require 'bolt/target'
18
18
  require 'bolt/version'
19
+ require 'bolt/util/on_access'
19
20
 
20
21
  module Bolt
21
22
  class CLIError < Bolt::Error
@@ -28,11 +29,23 @@ module Bolt
28
29
 
29
30
  class CLI
30
31
  class BoltOptionParser < OptionParser
32
+ def self.examples(cmd, desc)
33
+ <<-EXAMP
34
+ #{desc} a Windows host via WinRM, providing for the password
35
+ bolt #{cmd} -n winrm://winhost -u Administrator -p
36
+ #{desc} the local machine, a Linux host via SSH, and hosts from a group specified in an inventory file
37
+ bolt #{cmd} -n localhost,nixhost,node_group
38
+ #{desc} Windows hosts queried from PuppetDB via WinRM as a domain user, prompting for the password
39
+ bolt #{cmd} -q 'inventory[certname] { facts.os.family = "windows" }' --transport winrm -u 'domain\\Administrator' -p
40
+ EXAMP
41
+ end
42
+
31
43
  BANNER = <<-HELP
32
44
  Usage: bolt <subcommand> <action> [options]
33
45
 
34
46
  Available subcommands:
35
47
  bolt command run <command> Run a command remotely
48
+ bolt file upload <src> <dest> Upload a local file
36
49
  bolt script run <script> Upload a local script and run it remotely
37
50
  bolt task show Show list of available tasks
38
51
  bolt task show <task> Show documentation for task
@@ -40,7 +53,8 @@ Available subcommands:
40
53
  bolt plan show Show list of available plans
41
54
  bolt plan show <plan> Show details for plan
42
55
  bolt plan run <plan> [params] Run a Puppet task plan
43
- bolt file upload <src> <dest> Upload a local file
56
+
57
+ Run `bolt <subcommand> --help` to view specific examples.
44
58
 
45
59
  where [options] are:
46
60
  HELP
@@ -55,6 +69,7 @@ Available actions are:
55
69
 
56
70
  Parameters are of the form <parameter>=<value>.
57
71
 
72
+ #{examples('task run facts', 'run facter on')}
58
73
  Available options are:
59
74
  HELP
60
75
 
@@ -64,6 +79,7 @@ Usage: bolt command <action> <command> [options]
64
79
  Available actions are:
65
80
  run Run a command remotely
66
81
 
82
+ #{examples('command run hostname', 'run hostname on')}
67
83
  Available options are:
68
84
  HELP
69
85
 
@@ -73,6 +89,7 @@ Usage: bolt script <action> <script> [[arg1] ... [argN]] [options]
73
89
  Available actions are:
74
90
  run Upload a local script and run it remotely
75
91
 
92
+ #{examples('script run my_script.ps1 some args', 'run a script on')}
76
93
  Available options are:
77
94
  HELP
78
95
 
@@ -86,6 +103,7 @@ Available actions are:
86
103
 
87
104
  Parameters are of the form <parameter>=<value>.
88
105
 
106
+ #{examples('plan run canary command=hostname', 'run the canary plan on')}
89
107
  Available options are:
90
108
  HELP
91
109
 
@@ -95,6 +113,7 @@ Usage: bolt file <action> [options]
95
113
  Available actions are:
96
114
  upload <src> <dest> Upload local file <src> to <dest> on each node
97
115
 
116
+ #{examples('file upload /tmp/source /etc/profile.d/login.sh', 'upload a file to')}
98
117
  Available options are:
99
118
  HELP
100
119
 
@@ -119,7 +138,7 @@ Available options are:
119
138
  'Identifies the nodes to target.',
120
139
  'Enter a comma-separated list of node URIs or group names.',
121
140
  "Or read a node list from an input file '@<file>' or stdin '-'.",
122
- 'Example: --nodes localhost,node_group,ssh://nix.com:2222,winrm://windows.puppet.com',
141
+ 'Example: --nodes localhost,node_group,ssh://nix.com:23,winrm://windows.puppet.com',
123
142
  'URI format is [protocol://]host[:port]',
124
143
  "SSH is the default protocol; may be #{TRANSPORTS.keys.join(', ')}",
125
144
  'For Windows nodes, specify the winrm:// protocol if it has not be configured',
@@ -127,17 +146,27 @@ Available options are:
127
146
  'For WinRM, port defaults to `5985` or `5986` based on the --[no-]ssl setting') do |nodes|
128
147
  @options[:nodes] << get_arg_input(nodes)
129
148
  end.extend(SwitchHider)
130
- @query = define('-q', '--query QUERY',
131
- 'Query PuppetDB to determine the targets') do |query|
149
+ @query = define('-q', '--query QUERY', 'Query PuppetDB to determine the targets') do |query|
132
150
  @options[:query] = query
133
151
  end.extend(SwitchHider)
134
- define('-u', '--user USER',
135
- 'User to authenticate as') do |user|
152
+ define('--noop', 'Execute a task that supports it in noop mode') do |_|
153
+ @options[:noop] = true
154
+ end
155
+ define('--description DESCRIPTION',
156
+ 'Description to use for the job') do |description|
157
+ @options[:description] = description
158
+ end
159
+ define('--params PARAMETERS',
160
+ "Parameters to a task or plan as json, a json file '@<file>', or on stdin '-'") do |params|
161
+ @options[:task_options] = parse_params(params)
162
+ end
163
+
164
+ separator 'Authentication:'
165
+ define('-u', '--user USER', 'User to authenticate as') do |user|
136
166
  @options[:user] = user
137
167
  end
138
168
  define('-p', '--password [PASSWORD]',
139
- 'Password to authenticate with.',
140
- 'Omit the value to prompt for the password.') do |password|
169
+ 'Password to authenticate with. Omit the value to prompt for the password.') do |password|
141
170
  if password.nil?
142
171
  STDOUT.print "Please enter your password: "
143
172
  @options[:password] = STDIN.noecho(&:gets).chomp
@@ -146,59 +175,25 @@ Available options are:
146
175
  @options[:password] = password
147
176
  end
148
177
  end
149
- define('--private-key KEY',
150
- 'Private ssh key to authenticate with') do |key|
178
+ define('--private-key KEY', 'Private ssh key to authenticate with') do |key|
151
179
  @options[:'private-key'] = key
152
180
  end
153
- define('--tmpdir DIR',
154
- 'The directory to upload and execute temporary files on the target') do |tmpdir|
155
- @options[:tmpdir] = tmpdir
156
- end
157
- define('-c', '--concurrency CONCURRENCY', Integer,
158
- 'Maximum number of simultaneous connections ' \
159
- '(defaults to 100)') do |concurrency|
160
- @options[:concurrency] = concurrency
161
- end
162
- define('--connect-timeout TIMEOUT', Integer,
163
- 'Connection timeout (defaults vary)') do |timeout|
164
- @options[:'connect-timeout'] = timeout
165
- end
166
- define('--modulepath MODULES',
167
- 'List of directories containing modules, ' \
168
- "separated by '#{File::PATH_SEPARATOR}'") do |modulepath|
169
- @options[:modulepath] = modulepath.split(File::PATH_SEPARATOR)
170
- end
171
- define('--params PARAMETERS',
172
- 'Parameters to a task or plan') do |params|
173
- @options[:task_options] = parse_params(params)
174
- end
175
-
176
- define('--format FORMAT',
177
- 'Output format to use: human or json') do |format|
178
- @options[:format] = format
179
- end
180
- define('--[no-]host-key-check',
181
- 'Check host keys with SSH') do |host_key_check|
181
+ define('--[no-]host-key-check', 'Check host keys with SSH') do |host_key_check|
182
182
  @options[:'host-key-check'] = host_key_check
183
183
  end
184
- define('--[no-]ssl',
185
- 'Use SSL with WinRM') do |ssl|
184
+ define('--[no-]ssl', 'Use SSL with WinRM') do |ssl|
186
185
  @options[:ssl] = ssl
187
186
  end
188
- define('--[no-]ssl-verify',
189
- 'Verify remote host SSL certificate with WinRM') do |ssl_verify|
187
+ define('--[no-]ssl-verify', 'Verify remote host SSL certificate with WinRM') do |ssl_verify|
190
188
  @options[:'ssl-verify'] = ssl_verify
191
189
  end
192
- define('--transport TRANSPORT', TRANSPORTS.keys.map(&:to_s),
193
- "Specify a default transport: #{TRANSPORTS.keys.join(', ')}") do |t|
194
- @options[:transport] = t
195
- end
196
- define('--run-as USER',
197
- 'User to run as using privilege escalation') do |user|
190
+
191
+ separator 'Escalation:'
192
+ define('--run-as USER', 'User to run as using privilege escalation') do |user|
198
193
  @options[:'run-as'] = user
199
194
  end
200
195
  define('--sudo-password [PASSWORD]',
201
- 'Password for privilege escalation') do |password|
196
+ 'Password for privilege escalation. Omit the value to prompt for the password.') do |password|
202
197
  if password.nil?
203
198
  STDOUT.print "Please enter your privilege escalation password: "
204
199
  @options[:'sudo-password'] = STDIN.noecho(&:gets).chomp
@@ -207,35 +202,57 @@ Available options are:
207
202
  @options[:'sudo-password'] = password
208
203
  end
209
204
  end
210
- define('--configfile CONFIG_PATH',
211
- 'Specify where to load the config file from') do |path|
205
+
206
+ separator 'Run context:'
207
+ define('-c', '--concurrency CONCURRENCY', Integer,
208
+ 'Maximum number of simultaneous connections (default: 100)') do |concurrency|
209
+ @options[:concurrency] = concurrency
210
+ end
211
+ define('--modulepath MODULES',
212
+ "List of directories containing modules, separated by '#{File::PATH_SEPARATOR}'") do |modulepath|
213
+ @options[:modulepath] = modulepath.split(File::PATH_SEPARATOR)
214
+ end
215
+ define('--configfile FILEPATH',
216
+ 'Specify where to load config from (default: ~/.puppetlabs/bolt.yaml)') do |path|
212
217
  @options[:configfile] = path
213
218
  end
214
- define('--inventoryfile INVENTORY_PATH',
215
- 'Specify where to load the inventory file from') do |path|
219
+ define('--inventoryfile FILEPATH',
220
+ 'Specify where to load inventory from (default: ~/.puppetlabs/bolt/inventory.yaml)') do |path|
216
221
  if ENV.include?(Bolt::Inventory::ENVIRONMENT_VAR)
217
222
  raise Bolt::CLIError, "Cannot pass inventory file when #{Bolt::Inventory::ENVIRONMENT_VAR} is set"
218
223
  end
219
224
  @options[:inventoryfile] = path
220
225
  end
221
- define_tail('--[no-]tty',
222
- 'Request a pseudo TTY on nodes that support it') do |tty|
226
+
227
+ separator 'Transports:'
228
+ define('--transport TRANSPORT', TRANSPORTS.keys.map(&:to_s),
229
+ "Specify a default transport: #{TRANSPORTS.keys.join(', ')}") do |t|
230
+ @options[:transport] = t
231
+ end
232
+ define('--connect-timeout TIMEOUT', Integer, 'Connection timeout (defaults vary)') do |timeout|
233
+ @options[:'connect-timeout'] = timeout
234
+ end
235
+ define('--[no-]tty', 'Request a pseudo TTY on nodes that support it') do |tty|
223
236
  @options[:tty] = tty
224
237
  end
225
- define_tail('--noop',
226
- 'Execute a task that supports it in noop mode') do |_|
227
- @options[:noop] = true
238
+ define('--tmpdir DIR', 'The directory to upload and execute temporary files on the target') do |tmpdir|
239
+ @options[:tmpdir] = tmpdir
240
+ end
241
+
242
+ separator 'Display:'
243
+ define('--format FORMAT', 'Output format to use: human or json') do |format|
244
+ @options[:format] = format
228
245
  end
229
- define_tail('-h', '--help', 'Display help') do |_|
246
+ define('-h', '--help', 'Display help') do |_|
230
247
  @options[:help] = true
231
248
  end
232
- define_tail('--verbose', 'Display verbose logging') do |_|
249
+ define('--verbose', 'Display verbose logging') do |_|
233
250
  @options[:verbose] = true
234
251
  end
235
- define_tail('--debug', 'Display debug logging') do |_|
252
+ define('--debug', 'Display debug logging') do |_|
236
253
  @options[:debug] = true
237
254
  end
238
- define_tail('--version', 'Display the version') do |_|
255
+ define('--version', 'Display the version') do |_|
239
256
  puts Bolt::VERSION
240
257
  raise Bolt::CLIExit
241
258
  end
@@ -449,8 +466,10 @@ Available options are:
449
466
 
450
467
  def puppetdb_client
451
468
  return @puppetdb_client if @puppetdb_client
452
- puppetdb_config = Bolt::PuppetDB::Config.new(nil, config.puppetdb)
453
- @puppetdb_client = Bolt::PuppetDB::Client.from_config(puppetdb_config)
469
+ @puppetdb_client = Bolt::Util::OnAccess.new do
470
+ puppetdb_config = Bolt::PuppetDB::Config.new(nil, config.puppetdb)
471
+ Bolt::PuppetDB::Client.from_config(puppetdb_config)
472
+ end
454
473
  end
455
474
 
456
475
  def query_puppetdb_nodes(query)
@@ -511,7 +530,7 @@ Available options are:
511
530
  options[:task_options]['nodes'] = options[:nodes].join(',')
512
531
  end
513
532
  executor = Bolt::Executor.new(config, options[:noop], true)
514
- result = pal.run_plan(options[:object], options[:task_options], executor, inventory)
533
+ result = pal.run_plan(options[:object], options[:task_options], executor, inventory, puppetdb_client)
515
534
  outputter.print_plan_result(result)
516
535
  # An exception would have been raised if the plan failed
517
536
  code = 0
@@ -523,17 +542,19 @@ Available options are:
523
542
  outputter.print_head
524
543
 
525
544
  elapsed_time = Benchmark.realtime do
545
+ executor_opts = {}
546
+ executor_opts['_description'] = options[:description] if options.key?(:description)
526
547
  results =
527
548
  case options[:mode]
528
549
  when 'command'
529
- executor.run_command(targets, options[:object]) do |event|
550
+ executor.run_command(targets, options[:object], executor_opts) do |event|
530
551
  outputter.print_event(event)
531
552
  end
532
553
  when 'script'
533
554
  script = options[:object]
534
555
  validate_file('script', script)
535
556
  executor.run_script(
536
- targets, script, options[:leftovers]
557
+ targets, script, options[:leftovers], executor_opts
537
558
  ) do |event|
538
559
  outputter.print_event(event)
539
560
  end
@@ -542,7 +563,8 @@ Available options are:
542
563
  targets,
543
564
  options[:task_options],
544
565
  executor,
545
- inventory) do |event|
566
+ inventory,
567
+ options[:description]) do |event|
546
568
  outputter.print_event(event)
547
569
  end
548
570
  when 'file'
@@ -553,7 +575,7 @@ Available options are:
553
575
  raise Bolt::CLIError, "A destination path must be specified"
554
576
  end
555
577
  validate_file('source file', src)
556
- executor.file_upload(targets, src, dest) do |event|
578
+ executor.file_upload(targets, src, dest, executor_opts) do |event|
557
579
  outputter.print_event(event)
558
580
  end
559
581
  end