bolt 2.40.2 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bolt might be problematic. Click here for more details.

Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +19 -17
  3. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +25 -0
  4. data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +6 -8
  5. data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +7 -3
  6. data/lib/bolt/analytics.rb +3 -2
  7. data/lib/bolt/applicator.rb +11 -1
  8. data/lib/bolt/bolt_option_parser.rb +3 -113
  9. data/lib/bolt/catalog.rb +10 -29
  10. data/lib/bolt/cli.rb +54 -155
  11. data/lib/bolt/config.rb +62 -239
  12. data/lib/bolt/config/options.rb +58 -97
  13. data/lib/bolt/config/transport/local.rb +1 -0
  14. data/lib/bolt/config/transport/options.rb +8 -1
  15. data/lib/bolt/config/transport/orch.rb +1 -0
  16. data/lib/bolt/executor.rb +15 -5
  17. data/lib/bolt/inventory.rb +3 -2
  18. data/lib/bolt/inventory/group.rb +35 -4
  19. data/lib/bolt/inventory/inventory.rb +1 -1
  20. data/lib/bolt/logger.rb +115 -11
  21. data/lib/bolt/module.rb +10 -2
  22. data/lib/bolt/module_installer.rb +4 -2
  23. data/lib/bolt/module_installer/resolver.rb +65 -12
  24. data/lib/bolt/module_installer/specs/forge_spec.rb +8 -2
  25. data/lib/bolt/module_installer/specs/git_spec.rb +17 -2
  26. data/lib/bolt/outputter/human.rb +9 -5
  27. data/lib/bolt/outputter/json.rb +16 -16
  28. data/lib/bolt/outputter/rainbow.rb +3 -3
  29. data/lib/bolt/pal.rb +94 -14
  30. data/lib/bolt/pal/yaml_plan.rb +8 -2
  31. data/lib/bolt/pal/yaml_plan/evaluator.rb +7 -19
  32. data/lib/bolt/pal/yaml_plan/step.rb +3 -24
  33. data/lib/bolt/pal/yaml_plan/step/upload.rb +2 -2
  34. data/lib/bolt/pal/yaml_plan/transpiler.rb +6 -1
  35. data/lib/bolt/plugin.rb +3 -3
  36. data/lib/bolt/plugin/cache.rb +7 -7
  37. data/lib/bolt/plugin/module.rb +0 -23
  38. data/lib/bolt/plugin/puppet_connect_data.rb +77 -0
  39. data/lib/bolt/plugin/puppetdb.rb +1 -1
  40. data/lib/bolt/project.rb +54 -81
  41. data/lib/bolt/project_manager.rb +4 -3
  42. data/lib/bolt/project_manager/module_migrator.rb +6 -5
  43. data/lib/bolt/rerun.rb +1 -1
  44. data/lib/bolt/result.rb +6 -1
  45. data/lib/bolt/shell/bash.rb +9 -4
  46. data/lib/bolt/shell/bash/tmpdir.rb +4 -1
  47. data/lib/bolt/shell/powershell.rb +9 -5
  48. data/lib/bolt/shell/powershell/snippets.rb +37 -150
  49. data/lib/bolt/task.rb +1 -1
  50. data/lib/bolt/transport/base.rb +0 -9
  51. data/lib/bolt/transport/docker.rb +1 -125
  52. data/lib/bolt/transport/docker/connection.rb +86 -161
  53. data/lib/bolt/transport/local.rb +1 -9
  54. data/lib/bolt/transport/orch/connection.rb +1 -1
  55. data/lib/bolt/transport/ssh.rb +1 -2
  56. data/lib/bolt/transport/ssh/connection.rb +1 -1
  57. data/lib/bolt/validator.rb +2 -2
  58. data/lib/bolt/version.rb +1 -1
  59. data/lib/bolt_server/config.rb +1 -1
  60. data/lib/bolt_server/transport_app.rb +48 -31
  61. data/lib/bolt_spec/bolt_context.rb +9 -4
  62. data/lib/bolt_spec/plans.rb +1 -109
  63. data/libexec/bolt_catalog +1 -1
  64. data/modules/aggregate/plans/count.pp +21 -0
  65. data/modules/aggregate/plans/targets.pp +21 -0
  66. data/modules/puppet_connect/plans/test_input_data.pp +67 -0
  67. data/modules/puppetdb_fact/plans/init.pp +10 -0
  68. metadata +28 -19
  69. data/modules/aggregate/plans/nodes.pp +0 -36
@@ -11,18 +11,10 @@ module Bolt
11
11
  end
12
12
 
13
13
  def with_connection(target)
14
- if target.transport_config['bundled-ruby'] || target.name == 'localhost'
14
+ if target.transport_config['bundled-ruby']
15
15
  target.set_local_defaults
16
16
  end
17
17
 
18
- if target.name != 'localhost' &&
19
- !target.transport_config.key?('bundled-ruby')
20
- msg = "The local transport will default to using Bolt's Ruby interpreter and "\
21
- "setting the 'puppet-agent' feature in Bolt 3.0. Enable or disable these "\
22
- "defaults by setting 'bundled-ruby' in the local transport config."
23
- Bolt::Logger.warn_once('local default config', msg)
24
- end
25
-
26
18
  yield Connection.new(target)
27
19
  end
28
20
  end
@@ -21,7 +21,7 @@ module Bolt
21
21
 
22
22
  @logger = logger
23
23
  @key = self.class.get_key(opts)
24
- client_opts = opts.slice('token-file', 'cacert', 'job-poll-interval', 'job-poll-timeout')
24
+ client_opts = opts.slice('token-file', 'cacert', 'job-poll-interval', 'job-poll-timeout', 'read-timeout')
25
25
 
26
26
  if opts['service-url']
27
27
  uri = Addressable::URI.parse(opts['service-url'])
@@ -23,8 +23,7 @@ module Bolt
23
23
 
24
24
  def with_connection(target)
25
25
  if target.transport_config['ssh-command'] && !target.transport_config['native-ssh']
26
- Bolt::Logger.warn_once("ssh-command and native-ssh conflict",
27
- "native-ssh must be true to use ssh-command")
26
+ Bolt::Logger.warn_once("native_ssh_disabled", "native-ssh must be true to use ssh-command")
28
27
  end
29
28
 
30
29
  conn = if target.transport_config['native-ssh']
@@ -34,7 +34,7 @@ module Bolt
34
34
  begin
35
35
  Bolt::Util.validate_file('ssh key', target.options['private-key'])
36
36
  rescue Bolt::FileError => e
37
- @logger.warn(e.msg)
37
+ Bolt::Logger.warn("invalid_ssh_key", e.msg)
38
38
  end
39
39
  end
40
40
  end
@@ -147,7 +147,7 @@ module Bolt
147
147
  message += " at '#{path}'" if @path.any?
148
148
  message += " at #{@location}" if @location
149
149
  message += "."
150
- @warnings << message
150
+ @warnings << { id: 'unknown_option', msg: message }
151
151
  end
152
152
  end
153
153
 
@@ -160,7 +160,7 @@ module Bolt
160
160
  message = "Option '#{path}' "
161
161
  message += "at #{@location} " if @location
162
162
  message += "is deprecated. #{definition[:_deprecation]}"
163
- @deprecations << { option: key, message: message }
163
+ @deprecations << { id: "#{key}_option", msg: message }
164
164
  end
165
165
  end
166
166
 
data/lib/bolt/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '2.40.2'
4
+ VERSION = '3.1.0'
5
5
  end
@@ -9,7 +9,7 @@ module BoltServer
9
9
  def config_keys
10
10
  super + %w[concurrency cache-dir file-server-conn-timeout
11
11
  file-server-uri projects-dir environments-codedir
12
- environmentpath basemodulepath]
12
+ environmentpath basemodulepath builtin-content-dir]
13
13
  end
14
14
 
15
15
  def env_keys
@@ -133,7 +133,14 @@ module BoltServer
133
133
  task_data = body['task']
134
134
  task = Bolt::Task::PuppetServer.new(task_data['name'], task_data['metadata'], task_data['files'], @file_cache)
135
135
  parameters = body['parameters'] || {}
136
- [@executor.run_task(target, task, parameters), nil]
136
+ task_result = @executor.run_task(target, task, parameters)
137
+ task_result.each do |result|
138
+ value = result.value
139
+ next unless value.is_a?(Hash)
140
+ next unless value.key?('_sensitive')
141
+ value['_sensitive'] = value['_sensitive'].unwrap
142
+ end
143
+ [task_result, nil]
137
144
  end
138
145
 
139
146
  def run_command(target, body)
@@ -275,14 +282,19 @@ module BoltServer
275
282
  Bolt::Config.from_project(project, { log: { 'bolt-debug.log' => 'disable' } })
276
283
  end
277
284
 
285
+ def pal_from_project_bolt_config(bolt_config)
286
+ modulepath_object = Bolt::Config::Modulepath.new(
287
+ bolt_config.modulepath,
288
+ boltlib_path: [PE_BOLTLIB_PATH, Bolt::Config::Modulepath::BOLTLIB_PATH],
289
+ builtin_content_path: @config['builtin-content-dir']
290
+ )
291
+ Bolt::PAL.new(modulepath_object, nil, nil, nil, nil, nil, bolt_config.project)
292
+ end
293
+
278
294
  def in_bolt_project(versioned_project)
279
295
  @pal_mutex.synchronize do
280
296
  bolt_config = config_from_project(versioned_project)
281
- modulepath_object = Bolt::Config::Modulepath.new(
282
- bolt_config.modulepath,
283
- boltlib_path: [PE_BOLTLIB_PATH, Bolt::Config::Modulepath::BOLTLIB_PATH]
284
- )
285
- pal = Bolt::PAL.new(modulepath_object, nil, nil, nil, nil, nil, bolt_config.project)
297
+ pal = pal_from_project_bolt_config(bolt_config)
286
298
  context = {
287
299
  pal: pal,
288
300
  config: bolt_config
@@ -350,8 +362,8 @@ module BoltServer
350
362
  }
351
363
  end
352
364
 
353
- def allowed_helper(metadata, allowlist)
354
- allowed = allowlist.nil? || allowlist.include?(metadata['name']) ? true : false
365
+ def allowed_helper(pal, metadata, allowlist)
366
+ allowed = !pal.filter_content([metadata['name']], allowlist).empty?
355
367
  metadata.merge({ 'allowed' => allowed })
356
368
  end
357
369
 
@@ -365,21 +377,27 @@ module BoltServer
365
377
  plans.map { |plan_name| { 'name' => plan_name } }
366
378
  end
367
379
 
368
- def file_metadatas(pal, module_name, file)
369
- pal.in_bolt_compiler do
370
- mod = Puppet.lookup(:current_environment).module(module_name)
371
- raise ArgumentError, "`module_name`: #{module_name} does not exist" unless mod
372
- abs_file_path = mod.file(file)
373
- raise ArgumentError, "`file`: #{file} does not exist inside the module's 'files' directory" unless abs_file_path
374
- fileset = Puppet::FileServing::Fileset.new(abs_file_path, 'recurse' => 'yes')
375
- Puppet::FileServing::Fileset.merge(fileset).collect do |relative_file_path, base_path|
376
- metadata = Puppet::FileServing::Metadata.new(base_path, relative_path: relative_file_path)
377
- metadata.checksum_type = 'sha256'
378
- metadata.links = 'follow'
379
- metadata.collect
380
- metadata.to_data_hash
380
+ def file_metadatas(versioned_project, module_name, file)
381
+ abs_file_path = @pal_mutex.synchronize do
382
+ bolt_config = config_from_project(versioned_project)
383
+ pal = pal_from_project_bolt_config(bolt_config)
384
+ pal.in_bolt_compiler do
385
+ mod = Puppet.lookup(:current_environment).module(module_name)
386
+ raise ArgumentError, "`module_name`: #{module_name} does not exist" unless mod
387
+ mod.file(file)
381
388
  end
382
389
  end
390
+
391
+ raise ArgumentError, "`file`: #{file} does not exist inside the module's 'files' directory" unless abs_file_path
392
+
393
+ fileset = Puppet::FileServing::Fileset.new(abs_file_path, 'recurse' => 'yes')
394
+ Puppet::FileServing::Fileset.merge(fileset).collect do |relative_file_path, base_path|
395
+ metadata = Puppet::FileServing::Metadata.new(base_path, relative_path: relative_file_path)
396
+ metadata.checksum_type = 'sha256'
397
+ metadata.links = 'follow'
398
+ metadata.collect
399
+ metadata.to_data_hash
400
+ end
383
401
  end
384
402
 
385
403
  get '/' do
@@ -519,7 +537,7 @@ module BoltServer
519
537
  return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
520
538
  in_bolt_project(params['versioned_project']) do |context|
521
539
  plan_info = pe_plan_info(context[:pal], params[:module_name], params[:plan_name])
522
- plan_info = allowed_helper(plan_info, context[:config].project.plans)
540
+ plan_info = allowed_helper(context[:pal], plan_info, context[:config].project.plans)
523
541
  [200, plan_info.to_json]
524
542
  end
525
543
  rescue Bolt::Error => e
@@ -549,7 +567,7 @@ module BoltServer
549
567
  'versioned_project' => params['versioned_project']
550
568
  }
551
569
  task_info = pe_task_info(context[:pal], params[:module_name], params[:task_name], ps_parameters)
552
- task_info = allowed_helper(task_info, context[:config].project.tasks)
570
+ task_info = allowed_helper(context[:pal], task_info, context[:config].project.tasks)
553
571
  [200, task_info.to_json]
554
572
  end
555
573
  rescue Bolt::Error => e
@@ -589,7 +607,7 @@ module BoltServer
589
607
  plans_response = plan_list(context[:pal])
590
608
 
591
609
  # Dig in context for the allowlist of plans from project object
592
- plans_response.map! { |metadata| allowed_helper(metadata, context[:config].project.plans) }
610
+ plans_response.map! { |metadata| allowed_helper(context[:pal], metadata, context[:config].project.plans) }
593
611
 
594
612
  # We structure this array of plans to be an array of hashes so that it matches the structure
595
613
  # returned by the puppetserver API that serves data like this. Structuring the output this way
@@ -625,7 +643,7 @@ module BoltServer
625
643
  tasks_response = task_list(context[:pal])
626
644
 
627
645
  # Dig in context for the allowlist of tasks from project object
628
- tasks_response.map! { |metadata| allowed_helper(metadata, context[:config].project.tasks) }
646
+ tasks_response.map! { |metadata| allowed_helper(context[:pal], metadata, context[:config].project.tasks) }
629
647
 
630
648
  # We structure this array of tasks to be an array of hashes so that it matches the structure
631
649
  # returned by the puppetserver API that serves data like this. Structuring the output this way
@@ -641,12 +659,11 @@ module BoltServer
641
659
  #
642
660
  # @param versioned_project [String] the versioned_project to fetch the file metadatas from
643
661
  get '/project_file_metadatas/:module_name/*' do
644
- return MISSING_VERSIONED_PROJECT_RESPONSE if params['versioned_project'].nil?
645
- in_bolt_project(params['versioned_project']) do |context|
646
- file = params[:splat].first
647
- metadatas = file_metadatas(context[:pal], params[:module_name], file)
648
- [200, metadatas.to_json]
649
- end
662
+ versioned_project = params['versioned_project']
663
+ return MISSING_VERSIONED_PROJECT_RESPONSE if versioned_project.nil?
664
+ file = params[:splat].first
665
+ metadatas = file_metadatas(versioned_project, params[:module_name], file)
666
+ [200, metadatas.to_json]
650
667
  rescue Bolt::Error => e
651
668
  [400, e.to_json]
652
669
  rescue ArgumentError => e
@@ -130,11 +130,16 @@ module BoltSpec
130
130
  @executor ||= BoltSpec::Plans::MockExecutor.new(modulepath)
131
131
  end
132
132
 
133
- # Override in your tests
133
+ # Overrides inventory for tests.
134
134
  def inventory_data
135
135
  {}
136
136
  end
137
137
 
138
+ # Overrides configuration for tests.
139
+ def config_data
140
+ {}
141
+ end
142
+
138
143
  def inventory
139
144
  @inventory ||= Bolt::Inventory.create_version(inventory_data, config.transport, config.transports, plugins)
140
145
  end
@@ -142,7 +147,7 @@ module BoltSpec
142
147
  # Override in your tests
143
148
  def config
144
149
  @config ||= begin
145
- conf = Bolt::Config.default
150
+ conf = Bolt::Config.new(Bolt::Project.default_project, config_data)
146
151
  conf.modulepath = [modulepath].flatten
147
152
  conf
148
153
  end
@@ -161,7 +166,7 @@ module BoltSpec
161
166
  BoltSpec::Plans::MOCKED_ACTIONS.each do |action|
162
167
  # Allowed action stubs can be called up to be_called_times number of times
163
168
  define_method :"allow_#{action}" do |object|
164
- executor.send(:"stub_#{action}", object).add_stub
169
+ executor.send(:"stub_#{action}", object).add_stub(inventory)
165
170
  end
166
171
 
167
172
  # Expected action stubs must be called exactly the expected number of times
@@ -172,7 +177,7 @@ module BoltSpec
172
177
 
173
178
  # This stub will catch any action call if there are no stubs specifically for that task
174
179
  define_method :"allow_any_#{action}" do
175
- executor.send(:"stub_#{action}", :default).add_stub
180
+ executor.send(:"stub_#{action}", :default).add_stub(inventory)
176
181
  end
177
182
  end
178
183
 
@@ -5,119 +5,11 @@ require 'bolt_spec/plans/mock_executor'
5
5
  require 'bolt/pal'
6
6
 
7
7
  # These helpers are intended to be used for plan unit testing without calling
8
- # out to target nodes. It uses the BoltContext helper to set up a mock executor
8
+ # out to targets. It uses the BoltContext helper to set up a mock executor
9
9
  # which allows calls to run_* functions to be stubbed for testing. The context
10
10
  # helper also loads Bolt datatypes and plan functions to be used by the code
11
11
  # being tested.
12
12
  #
13
- # Stub matching
14
- #
15
- # Stubs match invocations of run_* functions by default matching any call but
16
- # with_targets and with_params helpers can further restrict the stub to match
17
- # more exact invocations. It's possible a call to run_* could match multiple
18
- # stubs. In this case the mock executor will first check for stubs specifically
19
- # matching the task being run after which it will use the last stub that
20
- # matched
21
- #
22
- #
23
- # allow vs expect
24
- #
25
- # Stubs have two general modes bases on whether the test is making assertions
26
- # on whether function was called. Allow stubs allow the run_* invocation to
27
- # be called any number of times while expect stubs will fail if no run_*
28
- # invocation matches them. The be_called_times(n) stub method can be used to
29
- # ensure an allow stub is not called more than n times or that an expect stub
30
- # is called exactly n times.
31
- #
32
- # Configuration
33
- #
34
- # To configure Puppet and Bolt at the beginning of tests, add the following
35
- # line to your spec_helper.rb:
36
- #
37
- # BoltSpec::Plans.init
38
- #
39
- # By default the plan helpers use the modulepath set up for rspec-puppet and
40
- # an otherwise empty bolt config and inventory. To create your own values for
41
- # these override the modulepath, config, or inventory methods.
42
- #
43
- # Sub-plan Execution
44
- #
45
- # When testing a plan, often times those plans call other plans in order to
46
- # build complex workflows. To support this we offer running in two different
47
- # modes:
48
- # execute_any_plan (default) - This mode will execute any plan that is encountered
49
- # without having to be stubbed/mocked. This default mode allows for plan control
50
- # flow to behave as normal. If you choose to stub/mock out a sub-plan in this mode
51
- # that will be honored and the sub-plan will not be executed. We will use the modifiers
52
- # on the stub to check for the conditions specified (example: be_called_times(3))
53
- #
54
- # execute_no_plan - This mode will not execute a plans that it encounters. Instead, when
55
- # a plan is encountered it will throw an error unless the plan is mocked out. This
56
- # mode is useful for ensuring that there are no plans called that you do not expect.
57
- # This plan requires authors to mock out all sub-plans that may be invoked when running
58
- # tests.
59
- #
60
- # TODO:
61
- # - Allow description based stub matching
62
- # - Better testing of plan errors
63
- # - Better error collection around call counts. Show what stubs exists and more than a single failure
64
- # - Allow stubbing with a block(at the double level? As a matched stub?)
65
- # - package code so that it can be used for testing modules outside of this repo
66
- # - set subject from describe and provide matchers similar to rspec puppets function tests
67
- # - Allow specific plans to be executed when running in execute_no_plan mode.
68
- #
69
- # MAYBE TODO?:
70
- # - validate call expectations at the end of the example instead of in run_plan
71
- # - resultset matchers to help testing canary like plans?
72
- # - inventory matchers to help testing plans that change inventory
73
- #
74
- # Flags:
75
- # - execute_any_plan: execute any plan that is encountered unless it is mocked (default)
76
- # - execute_no_plan: throw an error if a plan is encountered that is not stubbed
77
- #
78
- # Stubs:
79
- # - allow_command(cmd), expect_command(cmd): expect the exact command
80
- # - allow_plan(plan), expect_plan(plan): expect the named plan
81
- # - allow_script(script), expect_script(script): expect the script as <module>/path/to/file
82
- # - allow_task(task), expect_task(task): expect the named task
83
- # - allow_download(file), expect_download(file): expect the identified source file
84
- # - allow_upload(file), expect_upload(file): expect the identified source file
85
- # - allow_apply_prep: allows `apply_prep` to be invoked in the plan but does not allow modifiers
86
- # - allow_apply: allows `apply` to be invoked in the plan but does not allow modifiers
87
- # - allow_out_message, expect_out_message: expect a message to be passed to out::message (only modifiers are
88
- # be_called_times(n), with_params(params), and not_be_called)
89
- #
90
- # Stub modifiers:
91
- # - be_called_times(n): if allowed, fail if the action is called more than 'n' times
92
- # if expected, fail unless the action is called 'n' times
93
- # - not_be_called: fail if the action is called
94
- # - with_targets(targets): target or list of targets that you expect to be passed to the action
95
- # plan: does not support this modifier
96
- # - with_params(params): list of params and metaparams (or options) that you expect to be passed to the action.
97
- # Corresponds to the action's last argument.
98
- # - with_destination(dest): for upload_file and download_file, the expected destination path
99
- # - always_return(value): return a Bolt::ResultSet of Bolt::Result objects with the specified value Hash
100
- # plan: returns a Bolt::PlanResult with the specified value with a status of 'success'
101
- # command and script: only accept 'stdout' and 'stderr' keys
102
- # upload: does not support this modifier
103
- # download: does not support this modifier
104
- # - return_for_targets(targets_to_values): return a Bolt::ResultSet of Bolt::Result objects from the Hash mapping
105
- # targets to their value Hashes
106
- # command and script: only accept 'stdout' and 'stderr' keys
107
- # upload: does not support this modifier
108
- # download: does not support this modifier
109
- # plan: does not support this modifier
110
- # - return(&block): invoke the block to construct a Bolt::ResultSet. The blocks parameters differ based on action
111
- # command: `{ |targets:, command:, params:| ... }`
112
- # plan: `{ |plan:, params:| ... }`
113
- # script: `{ |targets:, script:, params:| ... }`
114
- # task: `{ |targets:, task:, params:| ... }`
115
- # upload: `{ |targets:, source:, destination:, params:| ... }`
116
- # download: `{ |targets:, source:, destination:, params:| ... }`
117
- # - error_with(err): return a failing Bolt::ResultSet, with Bolt::Result objects with the identified err hash
118
- # plans will throw a Bolt::PlanFailure that will be returned as the value of
119
- # the Bolt::PlanResult object with a status of 'failure'.
120
- #
121
13
  # Example:
122
14
  # describe "my_plan" do
123
15
  # it 'should return' do
data/libexec/bolt_catalog CHANGED
@@ -56,7 +56,7 @@ when "compile"
56
56
  else
57
57
  e.message
58
58
  end
59
- puts({ message: message }.to_json)
59
+ puts({ message: message, backtrace: e.backtrace }.to_json)
60
60
  exit 1
61
61
  rescue StandardError => e
62
62
  puts({ message: e.message }.to_json)
@@ -1,3 +1,24 @@
1
+ # @summary
2
+ # Run a task, command, or script on targets and aggregate the results as
3
+ # a count of targets for each value of a key.
4
+ #
5
+ # This plan accepts an action and a list of targets. The action can be the name
6
+ # of a task, a script, or a command to run. It will run the action on the
7
+ # targets and aggregate the key/value pairs in each Result into a hash, mapping
8
+ # the keys to a hash of each distinct value and how many targets returned that
9
+ # value for the key.
10
+ #
11
+ # @param command
12
+ # The command to run. Mutually exclusive with script and task.
13
+ # @param script
14
+ # The path to the script to run. Mutually exclusive with command and task.
15
+ # @param task
16
+ # The name of the task to run. Mutually exclusive with command and script.
17
+ # @param targets
18
+ # The list of targets to run the action on.
19
+ # @param params
20
+ # A hash of parameters and options to pass to the `run_*` function
21
+ # associated with the action (e.g. run_task).
1
22
  plan aggregate::count(
2
23
  Optional[String[0]] $task = undef,
3
24
  Optional[String[0]] $command = undef,
@@ -1,3 +1,24 @@
1
+ # @summary
2
+ # Run a task, command, or script on targets and aggregate the results as
3
+ # the list of targets for each value of a key in the results.
4
+ #
5
+ # This plan accepts an action and a list of targets. The action can be the name
6
+ # of a task, a script, or a command to run. It will run the action on the
7
+ # targets and aggregate the key/value pairs in each Result into a hash, mapping
8
+ # the keys to a hash of each distinct value and a list of targets returning that
9
+ # value.
10
+ #
11
+ # @param command
12
+ # The command to run. Mutually exclusive with script and task.
13
+ # @param script
14
+ # The path to the script to run. Mutually exclusive with command and task.
15
+ # @param task
16
+ # The name of the task to run. Mutually exclusive with command and script.
17
+ # @param targets
18
+ # The list of targets to run the action on.
19
+ # @param params
20
+ # A hash of parameters and options to pass to the `run_*` function
21
+ # associated with the action (e.g. run_task).
1
22
  plan aggregate::targets(
2
23
  Optional[String[0]] $task = undef,
3
24
  Optional[String[0]] $command = undef,