bolt 2.15.0 → 2.20.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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +1 -0
  3. data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +1 -0
  4. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +20 -9
  5. data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -0
  6. data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +123 -0
  7. data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +1 -0
  8. data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +1 -0
  9. data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +1 -0
  10. data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +1 -0
  11. data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +1 -0
  12. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +1 -0
  13. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +1 -0
  14. data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +1 -0
  15. data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +1 -0
  16. data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +1 -0
  17. data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +3 -0
  18. data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +2 -1
  19. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +7 -4
  20. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +2 -1
  21. data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +1 -0
  22. data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +1 -0
  23. data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +1 -0
  24. data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +1 -0
  25. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -0
  26. data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +1 -0
  27. data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +1 -0
  28. data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +1 -0
  29. data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +1 -0
  30. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +2 -0
  31. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +2 -0
  32. data/bolt-modules/file/lib/puppet/functions/file/exists.rb +1 -0
  33. data/bolt-modules/file/lib/puppet/functions/file/join.rb +2 -0
  34. data/bolt-modules/file/lib/puppet/functions/file/read.rb +2 -0
  35. data/bolt-modules/file/lib/puppet/functions/file/readable.rb +2 -0
  36. data/bolt-modules/file/lib/puppet/functions/file/write.rb +2 -0
  37. data/bolt-modules/out/lib/puppet/functions/out/message.rb +2 -0
  38. data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +1 -0
  39. data/bolt-modules/system/lib/puppet/functions/system/env.rb +2 -0
  40. data/lib/bolt/applicator.rb +21 -15
  41. data/lib/bolt/apply_result.rb +1 -1
  42. data/lib/bolt/bolt_option_parser.rb +55 -20
  43. data/lib/bolt/catalog.rb +3 -2
  44. data/lib/bolt/cli.rb +116 -47
  45. data/lib/bolt/config.rb +48 -148
  46. data/lib/bolt/config/options.rb +488 -0
  47. data/lib/bolt/config/transport/base.rb +16 -16
  48. data/lib/bolt/config/transport/docker.rb +9 -23
  49. data/lib/bolt/config/transport/local.rb +6 -44
  50. data/lib/bolt/config/transport/options.rb +460 -0
  51. data/lib/bolt/config/transport/orch.rb +9 -18
  52. data/lib/bolt/config/transport/remote.rb +3 -6
  53. data/lib/bolt/config/transport/ssh.rb +74 -154
  54. data/lib/bolt/config/transport/winrm.rb +18 -47
  55. data/lib/bolt/executor.rb +15 -0
  56. data/lib/bolt/inventory/group.rb +4 -3
  57. data/lib/bolt/inventory/inventory.rb +4 -17
  58. data/lib/bolt/inventory/target.rb +18 -5
  59. data/lib/bolt/logger.rb +24 -1
  60. data/lib/bolt/outputter.rb +1 -1
  61. data/lib/bolt/outputter/rainbow.rb +14 -3
  62. data/lib/bolt/pal.rb +31 -11
  63. data/lib/bolt/pal/yaml_plan/evaluator.rb +19 -2
  64. data/lib/bolt/pal/yaml_plan/step.rb +11 -2
  65. data/lib/bolt/pal/yaml_plan/step/download.rb +38 -0
  66. data/lib/bolt/pal/yaml_plan/step/upload.rb +3 -3
  67. data/lib/bolt/plugin/module.rb +2 -4
  68. data/lib/bolt/plugin/puppetdb.rb +3 -2
  69. data/lib/bolt/project.rb +41 -44
  70. data/lib/bolt/puppetdb/client.rb +2 -0
  71. data/lib/bolt/puppetdb/config.rb +16 -0
  72. data/lib/bolt/result.rb +7 -0
  73. data/lib/bolt/shell/bash.rb +53 -45
  74. data/lib/bolt/shell/powershell.rb +23 -12
  75. data/lib/bolt/shell/powershell/snippets.rb +15 -6
  76. data/lib/bolt/transport/base.rb +24 -0
  77. data/lib/bolt/transport/docker.rb +17 -5
  78. data/lib/bolt/transport/docker/connection.rb +20 -2
  79. data/lib/bolt/transport/local/connection.rb +14 -1
  80. data/lib/bolt/transport/orch.rb +20 -0
  81. data/lib/bolt/transport/simple.rb +6 -0
  82. data/lib/bolt/transport/ssh.rb +7 -1
  83. data/lib/bolt/transport/ssh/connection.rb +9 -1
  84. data/lib/bolt/transport/ssh/exec_connection.rb +23 -2
  85. data/lib/bolt/transport/winrm/connection.rb +109 -8
  86. data/lib/bolt/util.rb +26 -11
  87. data/lib/bolt/version.rb +1 -1
  88. data/lib/bolt_server/transport_app.rb +3 -2
  89. data/lib/bolt_spec/bolt_context.rb +7 -2
  90. data/lib/bolt_spec/plans.rb +15 -2
  91. data/lib/bolt_spec/plans/action_stubs.rb +2 -1
  92. data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
  93. data/lib/bolt_spec/plans/mock_executor.rb +14 -1
  94. data/lib/bolt_spec/run.rb +22 -0
  95. data/libexec/bolt_catalog +3 -2
  96. metadata +20 -29
@@ -41,6 +41,7 @@ require 'bolt/plugin'
41
41
  # - allow_command(cmd), expect_command(cmd): expect the exact command
42
42
  # - allow_script(script), expect_script(script): expect the script as <module>/path/to/file
43
43
  # - allow_task(task), expect_task(task): expect the named task
44
+ # - allow_download(file), expect_download(file): expect the identified source file
44
45
  # - allow_upload(file), expect_upload(file): expect the identified source file
45
46
  # - allow_out_message, expect_out_message: expect a message to be passed to out::message (only modifiers are
46
47
  # be_called_times(n), with_params(params), and not_be_called)
@@ -52,19 +53,22 @@ require 'bolt/plugin'
52
53
  # - with_targets(targets): target or list of targets that you expect to be passed to the action
53
54
  # - with_params(params): list of params and metaparams (or options) that you expect to be passed to the action.
54
55
  # Corresponds to the action's last argument.
55
- # - with_destination(dest): for upload_file, the expected destination path
56
+ # - with_destination(dest): for upload_file and download_file, the expected destination path
56
57
  # - always_return(value): return a Bolt::ResultSet of Bolt::Result objects with the specified value Hash
57
58
  # command and script: only accept 'stdout' and 'stderr' keys
58
59
  # upload: does not support this modifier
60
+ # download: does not support this modifier
59
61
  # - return_for_targets(targets_to_values): return a Bolt::ResultSet of Bolt::Result objects from the Hash mapping
60
62
  # targets to their value Hashes
61
63
  # command and script: only accept 'stdout' and 'stderr' keys
62
64
  # upload: does not support this modifier
65
+ # download: does not support this modifier
63
66
  # - return(&block): invoke the block to construct a Bolt::ResultSet. The blocks parameters differ based on action
64
67
  # command: `{ |targets:, command:, params:| ... }`
65
68
  # script: `{ |targets:, script:, params:| ... }`
66
69
  # task: `{ |targets:, task:, params:| ... }`
67
70
  # upload: `{ |targets:, source:, destination:, params:| ... }`
71
+ # download: `{ |targets:, source:, destination:, params:| ... }`
68
72
  # - error_with(err): return a failing Bolt::ResultSet, with Bolt::Result objects with the identified err hash
69
73
  #
70
74
  # Example:
@@ -190,8 +194,9 @@ module BoltSpec
190
194
  # so it probably should be set separately
191
195
  # def allow_script(script_name)
192
196
  #
193
- # file uploads have a single destination and no arguments
197
+ # file uploads and downloads have a single destination and no arguments
194
198
  # def allow_file_upload(source_name)
199
+ # def allow_file_download(source_name)
195
200
  #
196
201
  # Most of the information in commands is in the command string itself
197
202
  # we may need more flexible allows than just the name/command string
@@ -80,6 +80,7 @@ require 'bolt/pal'
80
80
  # - allow_plan(plan), expect_plan(plan): expect the named plan
81
81
  # - allow_script(script), expect_script(script): expect the script as <module>/path/to/file
82
82
  # - allow_task(task), expect_task(task): expect the named task
83
+ # - allow_download(file), expect_download(file): expect the identified source file
83
84
  # - allow_upload(file), expect_upload(file): expect the identified source file
84
85
  # - allow_apply_prep: allows `apply_prep` to be invoked in the plan but does not allow modifiers
85
86
  # - allow_apply: allows `apply` to be invoked in the plan but does not allow modifiers
@@ -94,15 +95,17 @@ require 'bolt/pal'
94
95
  # plan: does not support this modifier
95
96
  # - with_params(params): list of params and metaparams (or options) that you expect to be passed to the action.
96
97
  # Corresponds to the action's last argument.
97
- # - with_destination(dest): for upload_file, the expected destination path
98
+ # - with_destination(dest): for upload_file and download_file, the expected destination path
98
99
  # - always_return(value): return a Bolt::ResultSet of Bolt::Result objects with the specified value Hash
99
100
  # plan: returns a Bolt::PlanResult with the specified value with a status of 'success'
100
101
  # command and script: only accept 'stdout' and 'stderr' keys
101
102
  # upload: does not support this modifier
103
+ # download: does not support this modifier
102
104
  # - return_for_targets(targets_to_values): return a Bolt::ResultSet of Bolt::Result objects from the Hash mapping
103
105
  # targets to their value Hashes
104
106
  # command and script: only accept 'stdout' and 'stderr' keys
105
107
  # upload: does not support this modifier
108
+ # download: does not support this modifier
106
109
  # plan: does not support this modifier
107
110
  # - return(&block): invoke the block to construct a Bolt::ResultSet. The blocks parameters differ based on action
108
111
  # command: `{ |targets:, command:, params:| ... }`
@@ -110,6 +113,7 @@ require 'bolt/pal'
110
113
  # script: `{ |targets:, script:, params:| ... }`
111
114
  # task: `{ |targets:, task:, params:| ... }`
112
115
  # upload: `{ |targets:, source:, destination:, params:| ... }`
116
+ # download: `{ |targets:, source:, destination:, params:| ... }`
113
117
  # - error_with(err): return a failing Bolt::ResultSet, with Bolt::Result objects with the identified err hash
114
118
  # plans will throw a Bolt::PlanFailure that will be returned as the value of
115
119
  # the Bolt::PlanResult object with a status of 'failure'.
@@ -219,7 +223,16 @@ module BoltSpec
219
223
  end
220
224
 
221
225
  def run_plan(name, params)
222
- pal = Bolt::PAL.new(config.modulepath, config.hiera_config, config.project.resource_types)
226
+ pal = Bolt::PAL.new(
227
+ config.modulepath,
228
+ config.hiera_config,
229
+ config.project.resource_types,
230
+ config.compile_concurrency,
231
+ config.trusted_external,
232
+ config.apply_settings,
233
+ config.project
234
+ )
235
+
223
236
  result = executor.with_plan_allowed_exec(name, params) do
224
237
  pal.run_plan(name, params, executor, inventory, puppetdb_client)
225
238
  end
@@ -118,7 +118,7 @@ module BoltSpec
118
118
  # Restricts the stub to only match invocations with
119
119
  # the correct targets
120
120
  def with_targets(targets)
121
- targets = [targets] unless targets.is_a? Array
121
+ targets = Array(targets)
122
122
  @invocation[:targets] = targets.map do |target|
123
123
  if target.is_a? String
124
124
  target
@@ -193,3 +193,4 @@ require_relative 'action_stubs/plan_stub'
193
193
  require_relative 'action_stubs/script_stub'
194
194
  require_relative 'action_stubs/task_stub'
195
195
  require_relative 'action_stubs/upload_stub'
196
+ require_relative 'action_stubs/download_stub'
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module BoltSpec
4
+ module Plans
5
+ class DownloadStub < ActionStub
6
+ def matches(targets, _source, destination, options)
7
+ if @invocation[:targets] && Set.new(@invocation[:targets]) != Set.new(targets.map(&:name))
8
+ return false
9
+ end
10
+
11
+ if @invocation[:destination] && destination != @invocation[:destination]
12
+ return false
13
+ end
14
+
15
+ if @invocation[:options] && options != @invocation[:options]
16
+ return false
17
+ end
18
+
19
+ true
20
+ end
21
+
22
+ def call(targets, source, destination, options)
23
+ @calls += 1
24
+ if @return_block
25
+ results = @return_block.call(targets: targets, source: source, destination: destination, params: options)
26
+ check_resultset(results, source)
27
+ else
28
+ results = targets.map do |target|
29
+ if @data[:default].is_a?(Bolt::Error)
30
+ default_for(target)
31
+ else
32
+ download = File.join(destination, Bolt::Util.windows_basename(source))
33
+ Bolt::Result.for_download(target, source, destination, download)
34
+ end
35
+ end
36
+ Bolt::ResultSet.new(results)
37
+ end
38
+ end
39
+
40
+ def parameters
41
+ @invocation[:options]
42
+ end
43
+
44
+ def result_for(_target, _data)
45
+ raise 'Download result cannot be changed'
46
+ end
47
+
48
+ # Public methods
49
+
50
+ def always_return(_data)
51
+ raise 'Download result cannot be changed'
52
+ end
53
+
54
+ def with_destination(destination)
55
+ @invocation[:destination] = destination
56
+ self
57
+ end
58
+
59
+ def with_params(params)
60
+ @invocation[:options] = params.select { |k, _v| k.start_with?('_') }
61
+ .transform_keys { |k| k.sub(/^_/, '').to_sym }
62
+ self
63
+ end
64
+ end
65
+ end
66
+ end
@@ -11,7 +11,7 @@ require 'set'
11
11
 
12
12
  module BoltSpec
13
13
  module Plans
14
- MOCKED_ACTIONS = %i[command plan script task upload].freeze
14
+ MOCKED_ACTIONS = %i[command download plan script task upload].freeze
15
15
 
16
16
  class UnexpectedInvocation < ArgumentError; end
17
17
 
@@ -90,6 +90,19 @@ module BoltSpec
90
90
  result
91
91
  end
92
92
 
93
+ def download_file(targets, source, destination, options = {})
94
+ result = nil
95
+ if (doub = @download_doubles[source] || @download_doubles[:default])
96
+ result = doub.process(targets, source, destination, options)
97
+ end
98
+ unless result
99
+ targets = targets.map(&:name)
100
+ @error_message = "Unexpected call to 'download_file(#{source}, #{destination}, #{targets}, #{options})'"
101
+ raise UnexpectedInvocation, @error_message
102
+ end
103
+ result
104
+ end
105
+
93
106
  def upload_file(targets, source_path, destination, options = {})
94
107
  source = module_file_id(source_path)
95
108
  result = nil
@@ -80,6 +80,22 @@ module BoltSpec
80
80
  Bolt::Util.walk_keys(result, &:to_s)
81
81
  end
82
82
 
83
+ def download_file(source, dest, targets, options: {}, config: nil, inventory: nil)
84
+ if config.nil? && defined?(bolt_config)
85
+ config = bolt_config
86
+ end
87
+
88
+ if inventory.nil? && defined?(bolt_inventory)
89
+ inventory = bolt_inventory
90
+ end
91
+
92
+ result = BoltRunner.with_runner(config, inventory) do |runner|
93
+ runner.download_file(source, dest, targets, options)
94
+ end
95
+ result = result.to_a
96
+ Bolt::Util.walk_keys(result, &:to_s)
97
+ end
98
+
83
99
  def upload_file(source, dest, targets, options: {}, config: nil, inventory: nil)
84
100
  if config.nil? && defined?(bolt_config)
85
101
  config = bolt_config
@@ -194,6 +210,12 @@ module BoltSpec
194
210
  executor.run_script(targets, script, arguments, options)
195
211
  end
196
212
 
213
+ def download_file(source, dest, targets, options = {})
214
+ executor = Bolt::Executor.new(config.concurrency, @analytics)
215
+ targets = inventory.get_targets(targets)
216
+ executor.download_file(targets, source, dest, options)
217
+ end
218
+
197
219
  def upload_file(source, dest, targets, options = {})
198
220
  executor = Bolt::Executor.new(config.concurrency, @analytics)
199
221
  targets = inventory.get_targets(targets)
@@ -32,10 +32,11 @@ require 'json'
32
32
  # }
33
33
 
34
34
  command = ARGV[0]
35
- if command == "parse"
35
+ case command
36
+ when "parse"
36
37
  code = File.open(ARGV[1], &:read)
37
38
  puts JSON.pretty_generate(Bolt::Catalog.new.generate_ast(code, ARGV[1]))
38
- elsif command == "compile"
39
+ when "compile"
39
40
  request = if ARGV[1]
40
41
  File.open(ARGV[1]) { |fh| JSON.parse(fh.read) }
41
42
  else
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.15.0
4
+ version: 2.20.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-06-22 00:00:00.000000000 Z
11
+ date: 2020-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -178,20 +178,6 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: '0.4'
181
- - !ruby/object:Gem::Dependency
182
- name: paint
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: '2.2'
188
- type: :runtime
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: '2.2'
195
181
  - !ruby/object:Gem::Dependency
196
182
  name: puppet
197
183
  requirement: !ruby/object:Gem::Requirement
@@ -213,47 +199,47 @@ dependencies:
213
199
  - !ruby/object:Gem::Version
214
200
  version: '7'
215
201
  - !ruby/object:Gem::Dependency
216
- name: puppet-resource_api
202
+ name: puppetfile-resolver
217
203
  requirement: !ruby/object:Gem::Requirement
218
204
  requirements:
219
- - - ">="
205
+ - - "~>"
220
206
  - !ruby/object:Gem::Version
221
- version: 1.8.1
207
+ version: 0.1.0
222
208
  type: :runtime
223
209
  prerelease: false
224
210
  version_requirements: !ruby/object:Gem::Requirement
225
211
  requirements:
226
- - - ">="
212
+ - - "~>"
227
213
  - !ruby/object:Gem::Version
228
- version: 1.8.1
214
+ version: 0.1.0
229
215
  - !ruby/object:Gem::Dependency
230
- name: puppet-strings
216
+ name: puppet-resource_api
231
217
  requirement: !ruby/object:Gem::Requirement
232
218
  requirements:
233
- - - "~>"
219
+ - - ">="
234
220
  - !ruby/object:Gem::Version
235
- version: '2.3'
221
+ version: 1.8.1
236
222
  type: :runtime
237
223
  prerelease: false
238
224
  version_requirements: !ruby/object:Gem::Requirement
239
225
  requirements:
240
- - - "~>"
226
+ - - ">="
241
227
  - !ruby/object:Gem::Version
242
- version: '2.3'
228
+ version: 1.8.1
243
229
  - !ruby/object:Gem::Dependency
244
- name: puppetfile-resolver
230
+ name: puppet-strings
245
231
  requirement: !ruby/object:Gem::Requirement
246
232
  requirements:
247
233
  - - "~>"
248
234
  - !ruby/object:Gem::Version
249
- version: 0.1.0
235
+ version: '2.3'
250
236
  type: :runtime
251
237
  prerelease: false
252
238
  version_requirements: !ruby/object:Gem::Requirement
253
239
  requirements:
254
240
  - - "~>"
255
241
  - !ruby/object:Gem::Version
256
- version: 0.1.0
242
+ version: '2.3'
257
243
  - !ruby/object:Gem::Dependency
258
244
  name: r10k
259
245
  requirement: !ruby/object:Gem::Requirement
@@ -412,6 +398,7 @@ files:
412
398
  - bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb
413
399
  - bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb
414
400
  - bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb
401
+ - bolt-modules/boltlib/lib/puppet/functions/download_file.rb
415
402
  - bolt-modules/boltlib/lib/puppet/functions/facts.rb
416
403
  - bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb
417
404
  - bolt-modules/boltlib/lib/puppet/functions/get_resources.rb
@@ -460,9 +447,11 @@ files:
460
447
  - lib/bolt/catalog/logging.rb
461
448
  - lib/bolt/cli.rb
462
449
  - lib/bolt/config.rb
450
+ - lib/bolt/config/options.rb
463
451
  - lib/bolt/config/transport/base.rb
464
452
  - lib/bolt/config/transport/docker.rb
465
453
  - lib/bolt/config/transport/local.rb
454
+ - lib/bolt/config/transport/options.rb
466
455
  - lib/bolt/config/transport/orch.rb
467
456
  - lib/bolt/config/transport/remote.rb
468
457
  - lib/bolt/config/transport/ssh.rb
@@ -491,6 +480,7 @@ files:
491
480
  - lib/bolt/pal/yaml_plan/parameter.rb
492
481
  - lib/bolt/pal/yaml_plan/step.rb
493
482
  - lib/bolt/pal/yaml_plan/step/command.rb
483
+ - lib/bolt/pal/yaml_plan/step/download.rb
494
484
  - lib/bolt/pal/yaml_plan/step/eval.rb
495
485
  - lib/bolt/pal/yaml_plan/step/plan.rb
496
486
  - lib/bolt/pal/yaml_plan/step/resources.rb
@@ -562,6 +552,7 @@ files:
562
552
  - lib/bolt_spec/plans.rb
563
553
  - lib/bolt_spec/plans/action_stubs.rb
564
554
  - lib/bolt_spec/plans/action_stubs/command_stub.rb
555
+ - lib/bolt_spec/plans/action_stubs/download_stub.rb
565
556
  - lib/bolt_spec/plans/action_stubs/plan_stub.rb
566
557
  - lib/bolt_spec/plans/action_stubs/script_stub.rb
567
558
  - lib/bolt_spec/plans/action_stubs/task_stub.rb