bolt 3.9.0 → 3.9.1

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
  SHA256:
3
- metadata.gz: 1c6c3fbb5bdf8e8b53493a029b46560616f2ea310092823f863de14ad1fc836b
4
- data.tar.gz: f4a3193539da70d75ff36f39a126d6f56710c91e2ff54c465a1477685b6fb19a
3
+ metadata.gz: 677d817ea21f24c36b06d830a6a4f60cc11a1c288b9bc948ad69ee47f59da4f9
4
+ data.tar.gz: a5045561603829eda876b5558082ecfa234916393ed4c92e6c5e7851c3cf1f2f
5
5
  SHA512:
6
- metadata.gz: e6c8837f2d6ef2e67ac2be71d150637bcb90af95207812ec22c81557841279a5f148f2348ca6e0d137e42bfd4058009c59439996a208dc6c5c72568a8842e498
7
- data.tar.gz: 712b2be84c5ff24749ef1e010d439e05057c48d648394f7d321611d7576a006277d476adb38c6892fa73b380a0288726023643c8b2849a00f9ac164e06fe805f
6
+ metadata.gz: 111b4df917e7788816f8ccbac0b1f7ed5ecb35af9ddec145aece1aa8ad8dd10c617383ce0b17b5e9146a528ad15e28751771eba0bef1fb08ddcd91c3db200c62
7
+ data.tar.gz: cea97329b768ee991b0757bd0a4ff7ae28b2f0a68b678989adaee488a4c98d2354c618bc4663be18482088e856307238e7e04ac823b3dd65a95465fc08ed8254
@@ -130,6 +130,9 @@ Puppet::Functions.create_function(:run_task) do
130
130
  end
131
131
  end
132
132
 
133
+ # Report whether the task was run in noop mode.
134
+ executor.report_noop_mode(executor.noop || options[:noop])
135
+
133
136
  if targets.empty?
134
137
  Bolt::ResultSet.new([])
135
138
  else
@@ -175,6 +175,9 @@ Puppet::Functions.create_function(:run_task_with) do
175
175
  end
176
176
  end
177
177
 
178
+ # Report whether the task was run in noop mode.
179
+ executor.report_noop_mode(executor.noop || options[:noop])
180
+
178
181
  if targets.empty?
179
182
  Bolt::ResultSet.new([])
180
183
  else
data/lib/bolt/executor.rb CHANGED
@@ -242,6 +242,10 @@ module Bolt
242
242
  @analytics&.event('Plan', plan_function, label: label)
243
243
  end
244
244
 
245
+ def report_noop_mode(noop)
246
+ @analytics&.event('Task', 'noop', label: (!!noop).to_s)
247
+ end
248
+
245
249
  def report_apply(statement_count, resource_counts)
246
250
  data = { statement_count: statement_count }
247
251
 
@@ -34,7 +34,7 @@ module Bolt
34
34
  local = Puppet::Parser::Scope::LocalScope.new
35
35
 
36
36
  # Compress the current scopes into a single vars hash to add to the new scope
37
- scope.to_hash.each_pair { |k, v| local[k] = v }
37
+ scope.to_hash(true, true).each_pair { |k, v| local[k] = v }
38
38
  newscope.push_ephemerals([local])
39
39
  end
40
40
 
data/lib/bolt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '3.9.0'
4
+ VERSION = '3.9.1'
5
5
  end
@@ -30,7 +30,7 @@ module BoltServer
30
30
  end
31
31
 
32
32
  def required_keys
33
- super + %w[file-server-uri]
33
+ super + %w[file-server-uri projects-dir]
34
34
  end
35
35
 
36
36
  def service_name
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/error'
4
+
5
+ module BoltServer
6
+ class RequestError < Bolt::Error
7
+ def initialize(msg, details = {})
8
+ super(msg, 'bolt-server/request-error', details)
9
+ end
10
+ end
11
+ end
@@ -10,6 +10,7 @@ require 'bolt/target'
10
10
  require 'bolt_server/file_cache'
11
11
  require 'bolt_server/plugin'
12
12
  require 'bolt_server/plugin/puppet_connect_data'
13
+ require 'bolt_server/request_error'
13
14
  require 'bolt/task/puppet_server'
14
15
  require 'json'
15
16
  require 'json-schema'
@@ -51,10 +52,6 @@ module BoltServer
51
52
  # See the `orchestrator.bolt.codedir` tk config setting.
52
53
  DEFAULT_BOLT_CODEDIR = '/opt/puppetlabs/server/data/orchestration-services/code'
53
54
 
54
- MISSING_VERSIONED_PROJECT_RESPONSE = [
55
- 400, Bolt::ValidationError.new('`versioned_project` is a required argument').to_json
56
- ].freeze
57
-
58
55
  def initialize(config)
59
56
  @config = config
60
57
  @schemas = Hash[REQUEST_SCHEMAS.map do |basename|
@@ -84,40 +81,29 @@ module BoltServer
84
81
  result
85
82
  end
86
83
 
87
- def error_result(error)
88
- {
89
- 'status' => 'failure',
90
- 'value' => { '_error' => error.to_h }
91
- }
92
- end
93
-
94
84
  def validate_schema(schema, body)
95
85
  schema_error = JSON::Validator.fully_validate(schema, body)
96
86
  if schema_error.any?
97
- Bolt::Error.new("There was an error validating the request body.",
98
- 'boltserver/schema-error',
99
- schema_error)
87
+ raise BoltServer::RequestError.new("There was an error validating the request body.",
88
+ schema_error)
100
89
  end
101
90
  end
102
91
 
103
92
  # Turns a Bolt::ResultSet object into a status hash that is fit
104
- # to return to the client in a response.
105
- #
106
- # If the `result_set` has more than one result, the status hash
107
- # will have a `status` value and a list of target `results`.
108
- # If the `result_set` contains only one item, it will be returned
109
- # as a single result object. Set `aggregate` to treat it as a set
110
- # of results with length 1 instead.
93
+ # to return to the client in a response. In the case of every action
94
+ # *except* check_node_connections the response will be a single serialized Result.
95
+ # In the check_node_connections case the response will be a hash with the top level "status"
96
+ # of the result and the serialized individual target results.
111
97
  def result_set_to_data(result_set, aggregate: false)
98
+ # use ResultSet#ok method to determine status of a (potentially) aggregate result before serializing
99
+ result_set_status = result_set.ok ? 'success' : 'failure'
112
100
  scrubbed_results = result_set.map do |result|
113
101
  scrub_stack_trace(result.to_data)
114
102
  end
115
103
 
116
- if aggregate || scrubbed_results.length > 1
117
- # For actions that act on multiple targets, construct a status hash for the aggregate result
118
- all_succeeded = scrubbed_results.all? { |r| r['status'] == 'success' }
104
+ if aggregate
119
105
  {
120
- status: all_succeeded ? 'success' : 'failure',
106
+ status: result_set_status,
121
107
  result: scrubbed_results
122
108
  }
123
109
  else
@@ -127,33 +113,26 @@ module BoltServer
127
113
  end
128
114
 
129
115
  def run_task(target, body)
130
- error = validate_schema(@schemas["action-run_task"], body)
131
- return [], error unless error.nil?
132
-
116
+ validate_schema(@schemas["action-run_task"], body)
133
117
  task_data = body['task']
134
118
  task = Bolt::Task::PuppetServer.new(task_data['name'], task_data['metadata'], task_data['files'], @file_cache)
135
119
  parameters = body['parameters'] || {}
136
- task_result = @executor.run_task(target, task, parameters)
137
- task_result.each do |result|
120
+ @executor.run_task(target, task, parameters).each do |result|
138
121
  value = result.value
139
122
  next unless value.is_a?(Hash)
140
123
  next unless value.key?('_sensitive')
141
124
  value['_sensitive'] = value['_sensitive'].unwrap
142
125
  end
143
- [task_result, nil]
144
126
  end
145
127
 
146
128
  def run_command(target, body)
147
- error = validate_schema(@schemas["action-run_command"], body)
148
- return [], error unless error.nil?
149
-
129
+ validate_schema(@schemas["action-run_command"], body)
150
130
  command = body['command']
151
- [@executor.run_command(target, command), nil]
131
+ @executor.run_command(target, command)
152
132
  end
153
133
 
154
134
  def check_node_connections(targets, body)
155
- error = validate_schema(@schemas["action-check_node_connections"], body)
156
- return [], error unless error.nil?
135
+ validate_schema(@schemas["action-check_node_connections"], body)
157
136
 
158
137
  # Puppet Enterprise's orchestrator service uses the
159
138
  # check_node_connections endpoint to check whether nodes that should be
@@ -161,13 +140,11 @@ module BoltServer
161
140
  # because the endpoint is meant to be used for a single check of all
162
141
  # nodes; External implementations of wait_until_available (like
163
142
  # orchestrator's) should contact the endpoint in their own loop.
164
- [@executor.wait_until_available(targets, wait_time: 0), nil]
143
+ @executor.wait_until_available(targets, wait_time: 0)
165
144
  end
166
145
 
167
146
  def upload_file(target, body)
168
- error = validate_schema(@schemas["action-upload_file"], body)
169
- return [], error unless error.nil?
170
-
147
+ validate_schema(@schemas["action-upload_file"], body)
171
148
  files = body['files']
172
149
  destination = body['destination']
173
150
  job_id = body['job_id']
@@ -190,8 +167,7 @@ module BoltServer
190
167
  # Create directory in cache so we can move files in.
191
168
  FileUtils.mkdir_p(path)
192
169
  else
193
- return [400, Bolt::Error.new("Invalid `kind` of '#{kind}' supplied. Must be `file` or `directory`.",
194
- 'boltserver/schema-error').to_json]
170
+ raise BoltServer::RequestError, "Invalid kind: '#{kind}' supplied. Must be 'file' or 'directory'."
195
171
  end
196
172
  end
197
173
  # We need to special case the scenario where only one file was
@@ -205,17 +181,14 @@ module BoltServer
205
181
  else
206
182
  cache_dir
207
183
  end
208
- [@executor.upload_file(target, upload_source, destination), nil]
184
+ @executor.upload_file(target, upload_source, destination)
209
185
  end
210
186
 
211
187
  def run_script(target, body)
212
- error = validate_schema(@schemas["action-run_script"], body)
213
- return [], error unless error.nil?
214
-
188
+ validate_schema(@schemas["action-run_script"], body)
215
189
  # Download the file onto the machine.
216
190
  file_location = @file_cache.update_file(body['script'])
217
-
218
- [@executor.run_script(target, file_location, body['arguments'])]
191
+ @executor.run_script(target, file_location, body['arguments'])
219
192
  end
220
193
 
221
194
  # This function is nearly identical to Bolt::Pal's `with_puppet_settings` with the
@@ -248,16 +221,14 @@ module BoltServer
248
221
  codedir = @config['environments-codedir'] || DEFAULT_BOLT_CODEDIR
249
222
  environmentpath = @config['environmentpath'] || "#{codedir}/environments"
250
223
  basemodulepath = @config['basemodulepath'] || "#{codedir}/modules:/opt/puppetlabs/puppet/modules"
251
- modulepath_dirs = nil
252
224
  with_pe_pal_init_settings(codedir, environmentpath, basemodulepath) do
253
225
  environment = Puppet.lookup(:environments).get!(environment_name)
254
- modulepath_dirs = environment.modulepath
226
+ environment.modulepath
255
227
  end
256
- modulepath_dirs
257
228
  end
258
229
 
259
230
  def in_pe_pal_env(environment)
260
- return [400, '`environment` is a required argument'] if environment.nil?
231
+ raise BoltServer::RequestError, "'environment' is a required argument" if environment.nil?
261
232
  @pal_mutex.synchronize do
262
233
  modulepath_obj = Bolt::Config::Modulepath.new(
263
234
  modulepath_from_environment(environment),
@@ -266,18 +237,16 @@ module BoltServer
266
237
  pal = Bolt::PAL.new(modulepath_obj, nil, nil)
267
238
  yield pal
268
239
  rescue Puppet::Environments::EnvironmentNotFound
269
- [400, {
270
- "class" => 'bolt/unknown-environment',
271
- "message" => "Environment #{environment} not found"
272
- }.to_json]
273
- rescue Bolt::Error => e
274
- [400, e.to_json]
240
+ raise BoltServer::RequestError, "environment: '#{environment}' does not exist"
275
241
  end
276
242
  end
277
243
 
278
244
  def config_from_project(versioned_project)
279
245
  project_dir = File.join(@config['projects-dir'], versioned_project)
280
- raise Bolt::ValidationError, "`versioned_project`: #{project_dir} does not exist" unless Dir.exist?(project_dir)
246
+ unless Dir.exist?(project_dir)
247
+ raise BoltServer::RequestError,
248
+ "versioned_project: '#{project_dir}' does not exist"
249
+ end
281
250
  project = Bolt::Project.create_project(project_dir)
282
251
  Bolt::Config.from_project(project, { log: { 'bolt-debug.log' => 'disable' } })
283
252
  end
@@ -383,12 +352,15 @@ module BoltServer
383
352
  pal = pal_from_project_bolt_config(bolt_config)
384
353
  pal.in_bolt_compiler do
385
354
  mod = Puppet.lookup(:current_environment).module(module_name)
386
- raise ArgumentError, "`module_name`: #{module_name} does not exist" unless mod
355
+ raise BoltServer::RequestError, "module_name: '#{module_name}' does not exist" unless mod
387
356
  mod.file(file)
388
357
  end
389
358
  end
390
359
 
391
- raise ArgumentError, "`file`: #{file} does not exist inside the module's 'files' directory" unless abs_file_path
360
+ unless abs_file_path
361
+ raise BoltServer::RequestError,
362
+ "file: '#{file}' does not exist inside the module's 'files' directory"
363
+ end
392
364
 
393
365
  fileset = Puppet::FileServing::Fileset.new(abs_file_path, 'recurse' => 'yes')
394
366
  Puppet::FileServing::Fileset.merge(fileset).collect do |relative_file_path, base_path|
@@ -466,17 +438,15 @@ module BoltServer
466
438
  content_type :json
467
439
  body = JSON.parse(request.body.read)
468
440
 
469
- error = validate_schema(@schemas["transport-ssh"], body)
470
- return [400, error_result(error).to_json] unless error.nil?
441
+ validate_schema(@schemas["transport-ssh"], body)
471
442
 
472
443
  targets = (body['targets'] || [body['target']]).map do |target|
473
444
  make_ssh_target(target)
474
445
  end
475
446
 
476
- result_set, error = method(params[:action]).call(targets, body)
477
- return [400, error.to_json] unless error.nil?
447
+ result_set = method(params[:action]).call(targets, body)
478
448
 
479
- aggregate = body['target'].nil?
449
+ aggregate = params[:action] == 'check_node_connections'
480
450
  [200, result_set_to_data(result_set, aggregate: aggregate).to_json]
481
451
  end
482
452
 
@@ -506,17 +476,15 @@ module BoltServer
506
476
  content_type :json
507
477
  body = JSON.parse(request.body.read)
508
478
 
509
- error = validate_schema(@schemas["transport-winrm"], body)
510
- return [400, error_result(error).to_json] unless error.nil?
479
+ validate_schema(@schemas["transport-winrm"], body)
511
480
 
512
481
  targets = (body['targets'] || [body['target']]).map do |target|
513
482
  make_winrm_target(target)
514
483
  end
515
484
 
516
- result_set, error = method(params[:action]).call(targets, body)
517
- return [400, error.to_json] if error
485
+ result_set = method(params[:action]).call(targets, body)
518
486
 
519
- aggregate = body['target'].nil?
487
+ aggregate = params[:action] == 'check_node_connections'
520
488
  [200, result_set_to_data(result_set, aggregate: aggregate).to_json]
521
489
  end
522
490
 
@@ -534,14 +502,12 @@ module BoltServer
534
502
  #
535
503
  # @param versioned_project [String] the project to fetch the plan from
536
504
  get '/project_plans/:module_name/:plan_name' do
537
- return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
505
+ raise BoltServer::RequestError, "'versioned_project' is a required argument" if params['versioned_project'].nil?
538
506
  in_bolt_project(params['versioned_project']) do |context|
539
507
  plan_info = pe_plan_info(context[:pal], params[:module_name], params[:plan_name])
540
508
  plan_info = allowed_helper(context[:pal], plan_info, context[:config].project.plans)
541
509
  [200, plan_info.to_json]
542
510
  end
543
- rescue Bolt::Error => e
544
- [400, e.to_json]
545
511
  end
546
512
 
547
513
  # Fetches the metadata for a single task
@@ -561,7 +527,7 @@ module BoltServer
561
527
  #
562
528
  # @param bolt_versioned_project [String] the reference to the bolt-project directory to load task metadata from
563
529
  get '/project_tasks/:module_name/:task_name' do
564
- return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
530
+ raise BoltServer::RequestError, "'versioned_project' is a required argument" if params['versioned_project'].nil?
565
531
  in_bolt_project(params['versioned_project']) do |context|
566
532
  ps_parameters = {
567
533
  'versioned_project' => params['versioned_project']
@@ -570,8 +536,6 @@ module BoltServer
570
536
  task_info = allowed_helper(context[:pal], task_info, context[:config].project.tasks)
571
537
  [200, task_info.to_json]
572
538
  end
573
- rescue Bolt::Error => e
574
- [400, e.to_json]
575
539
  end
576
540
 
577
541
  # Fetches the list of plans for an environment, optionally fetching all metadata for each plan
@@ -602,7 +566,7 @@ module BoltServer
602
566
  #
603
567
  # @param versioned_project [String] the project to fetch the list of plans from
604
568
  get '/project_plans' do
605
- return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
569
+ raise BoltServer::RequestError, "'versioned_project' is a required argument" if params['versioned_project'].nil?
606
570
  in_bolt_project(params['versioned_project']) do |context|
607
571
  plans_response = plan_list(context[:pal])
608
572
 
@@ -615,8 +579,6 @@ module BoltServer
615
579
  # to bolt-server smaller/simpler.
616
580
  [200, plans_response.to_json]
617
581
  end
618
- rescue Bolt::Error => e
619
- [400, e.to_json]
620
582
  end
621
583
 
622
584
  # Fetches the list of tasks for an environment
@@ -638,7 +600,7 @@ module BoltServer
638
600
  #
639
601
  # @param versioned_project [String] the project to fetch the list of tasks from
640
602
  get '/project_tasks' do
641
- return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
603
+ raise BoltServer::RequestError, "'versioned_project' is a required argument" if params['versioned_project'].nil?
642
604
  in_bolt_project(params['versioned_project']) do |context|
643
605
  tasks_response = task_list(context[:pal])
644
606
 
@@ -651,34 +613,28 @@ module BoltServer
651
613
  # to bolt-server smaller/simpler.
652
614
  [200, tasks_response.to_json]
653
615
  end
654
- rescue Bolt::Error => e
655
- [400, e.to_json]
656
616
  end
657
617
 
658
618
  # Implements puppetserver's file_metadatas endpoint for projects.
659
619
  #
660
620
  # @param versioned_project [String] the versioned_project to fetch the file metadatas from
661
621
  get '/project_file_metadatas/:module_name/*' do
662
- versioned_project = params['versioned_project']
663
- return MISSING_VERSIONED_PROJECT_RESPONSE if versioned_project.nil?
622
+ raise BoltServer::RequestError, "'versioned_project' is a required argument" if params['versioned_project'].nil?
664
623
  file = params[:splat].first
665
- metadatas = file_metadatas(versioned_project, params[:module_name], file)
624
+ metadatas = file_metadatas(params['versioned_project'], params[:module_name], file)
666
625
  [200, metadatas.to_json]
667
- rescue Bolt::Error => e
668
- [400, e.to_json]
669
626
  rescue ArgumentError => e
670
- [400, e.message]
627
+ [500, e.message]
671
628
  end
672
629
 
673
630
  # Returns a list of targets parsed from a Project inventory
674
631
  #
675
632
  # @param versioned_project [String] the versioned_project to compute the inventory from
676
633
  post '/project_inventory_targets' do
677
- return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
634
+ raise BoltServer::RequestError, "'versioned_project' is a required argument" if params['versioned_project'].nil?
678
635
  content_type :json
679
636
  body = JSON.parse(request.body.read)
680
- error = validate_schema(@schemas["connect-data"], body)
681
- return [400, error_result(error).to_json] unless error.nil?
637
+ validate_schema(@schemas["connect-data"], body)
682
638
  in_bolt_project(params['versioned_project']) do |context|
683
639
  if context[:config].inventoryfile &&
684
640
  context[:config].project.inventory_file.to_s !=
@@ -717,8 +673,6 @@ module BoltServer
717
673
 
718
674
  [200, target_list.to_json]
719
675
  end
720
- rescue Bolt::Error => e
721
- [500, e.to_json]
722
676
  end
723
677
 
724
678
  error 404 do
@@ -727,6 +681,20 @@ module BoltServer
727
681
  [404, err.to_json]
728
682
  end
729
683
 
684
+ error BoltServer::RequestError do |err|
685
+ [400, err.to_json]
686
+ end
687
+
688
+ error Bolt::Error do |err|
689
+ # In order to match the request code pattern, unknown plan/task content should 400. This also
690
+ # gives us an opportunity to trim the message instructing users to use CLI to show available content.
691
+ if ['bolt/unknown-plan', 'bolt/unknown-task'].include?(err.kind)
692
+ [404, BoltServer::RequestError.new(err.msg.split('.').first).to_json]
693
+ else
694
+ [500, err.to_json]
695
+ end
696
+ end
697
+
730
698
  error StandardError do
731
699
  e = env['sinatra.error']
732
700
  err = Bolt::Error.new("500: Unknown error: #{e.message}",
@@ -274,11 +274,7 @@ module BoltSpec
274
274
  local = Puppet::Parser::Scope::LocalScope.new
275
275
 
276
276
  # Compress the current scopes into a single vars hash to add to the new scope
277
- current_scope = scope.effective_symtable(true)
278
- until current_scope.nil?
279
- current_scope.instance_variable_get(:@symbols)&.each_pair { |k, v| local[k] = v }
280
- current_scope = current_scope.parent
281
- end
277
+ scope.to_hash(true, true).each_pair { |k, v| local[k] = v }
282
278
  newscope.push_ephemerals([local])
283
279
  end
284
280
 
@@ -325,6 +321,8 @@ module BoltSpec
325
321
 
326
322
  def report_yaml_plan(_plan); end
327
323
 
324
+ def report_noop_mode(_mode); end
325
+
328
326
  def shutdown; end
329
327
 
330
328
  def start_plan(_plan_context); end
data/lib/bolt_spec/run.rb CHANGED
@@ -182,7 +182,10 @@ module BoltSpec
182
182
  @pal ||= Bolt::PAL.new(Bolt::Config::Modulepath.new(config.modulepath),
183
183
  config.hiera_config,
184
184
  config.project.resource_types,
185
- config.compile_concurrency)
185
+ config.compile_concurrency,
186
+ config.trusted_external,
187
+ config.apply_settings,
188
+ config.project)
186
189
  end
187
190
 
188
191
  def resolve_targets(target_spec)
@@ -1,8 +1,13 @@
1
1
  # @summary
2
2
  # Tests that the provided Puppet Connect input data is complete, meaning that all consuming inventory targets are connectable.
3
- #
4
- # This plan should only be used as part of the copy-pastable "test input data"
5
- # workflow specified in the Puppet Connect docs.
3
+ # You should run this plan with the following command:
4
+ # PUPPET_CONNECT_INPUT_DATA=/path/to/input_data.yaml bolt plan run puppet_connect::test_input_data
5
+ # where /path/to/input_data.yaml is the path to the input_data.yaml file containing the key-value input for the
6
+ # puppet_connect_data plugin. If the plan fails on some targets, then you can use Bolt's --rerun option to rerun the plan on
7
+ # just the failed targets:
8
+ # PUPPET_CONNECT_INPUT_DATA=/path/to/input_data.yaml bolt plan run puppet_connect::test_input_data --rerun failure
9
+ # Note that this plan should only be used as part of the copy-pastable "test input data" workflow specified in the Puppet
10
+ # Connect docs.
6
11
  #
7
12
  # @param targets
8
13
  # The set of targets to test. Usually this should be 'all', the default.
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: 3.9.0
4
+ version: 3.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-05-25 00:00:00.000000000 Z
11
+ date: 2021-06-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -594,6 +594,7 @@ files:
594
594
  - lib/bolt_server/file_cache.rb
595
595
  - lib/bolt_server/plugin.rb
596
596
  - lib/bolt_server/plugin/puppet_connect_data.rb
597
+ - lib/bolt_server/request_error.rb
597
598
  - lib/bolt_server/schemas/action-check_node_connections.json
598
599
  - lib/bolt_server/schemas/action-run_command.json
599
600
  - lib/bolt_server/schemas/action-run_script.json