bolt 2.11.1 → 2.16.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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +1 -1
  3. data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +3 -2
  4. data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +1 -0
  5. data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +1 -0
  6. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +1 -1
  7. data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -0
  8. data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +1 -0
  9. data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +1 -0
  10. data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +2 -1
  11. data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +1 -0
  12. data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +1 -0
  13. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +1 -0
  14. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +1 -0
  15. data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +1 -0
  16. data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +1 -0
  17. data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +53 -0
  18. data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +1 -0
  19. data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +67 -1
  20. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +1 -0
  21. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +6 -3
  22. data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +8 -2
  23. data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +1 -0
  24. data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +1 -0
  25. data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +66 -43
  26. data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +1 -0
  27. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -0
  28. data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +1 -0
  29. data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +1 -0
  30. data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +1 -0
  31. data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +1 -0
  32. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +2 -0
  33. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +2 -0
  34. data/bolt-modules/file/lib/puppet/functions/file/exists.rb +2 -1
  35. data/bolt-modules/file/lib/puppet/functions/file/join.rb +2 -0
  36. data/bolt-modules/file/lib/puppet/functions/file/read.rb +3 -1
  37. data/bolt-modules/file/lib/puppet/functions/file/readable.rb +3 -1
  38. data/bolt-modules/file/lib/puppet/functions/file/write.rb +2 -0
  39. data/bolt-modules/out/lib/puppet/functions/out/message.rb +2 -0
  40. data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +1 -0
  41. data/bolt-modules/system/lib/puppet/functions/system/env.rb +2 -0
  42. data/lib/bolt/analytics.rb +21 -2
  43. data/lib/bolt/applicator.rb +20 -7
  44. data/lib/bolt/apply_inventory.rb +4 -0
  45. data/lib/bolt/apply_target.rb +4 -0
  46. data/lib/bolt/bolt_option_parser.rb +11 -10
  47. data/lib/bolt/catalog.rb +81 -68
  48. data/lib/bolt/cli.rb +18 -8
  49. data/lib/bolt/config.rb +152 -120
  50. data/lib/bolt/config/options.rb +321 -0
  51. data/lib/bolt/config/transport/base.rb +16 -16
  52. data/lib/bolt/config/transport/docker.rb +9 -23
  53. data/lib/bolt/config/transport/local.rb +6 -44
  54. data/lib/bolt/config/transport/options.rb +305 -0
  55. data/lib/bolt/config/transport/orch.rb +9 -18
  56. data/lib/bolt/config/transport/remote.rb +3 -6
  57. data/lib/bolt/config/transport/ssh.rb +59 -114
  58. data/lib/bolt/config/transport/winrm.rb +18 -47
  59. data/lib/bolt/executor.rb +14 -1
  60. data/lib/bolt/inventory/group.rb +1 -1
  61. data/lib/bolt/inventory/inventory.rb +4 -14
  62. data/lib/bolt/inventory/target.rb +22 -5
  63. data/lib/bolt/outputter.rb +3 -0
  64. data/lib/bolt/outputter/rainbow.rb +80 -0
  65. data/lib/bolt/pal.rb +6 -1
  66. data/lib/bolt/project.rb +66 -46
  67. data/lib/bolt/resource_instance.rb +10 -3
  68. data/lib/bolt/shell/bash.rb +9 -9
  69. data/lib/bolt/shell/powershell.rb +2 -1
  70. data/lib/bolt/shell/powershell/snippets.rb +8 -0
  71. data/lib/bolt/transport/docker.rb +1 -1
  72. data/lib/bolt/transport/local/connection.rb +2 -1
  73. data/lib/bolt/transport/ssh/connection.rb +35 -0
  74. data/lib/bolt/version.rb +1 -1
  75. data/lib/bolt_spec/bolt_context.rb +1 -1
  76. data/lib/bolt_spec/run.rb +1 -1
  77. metadata +23 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5e8e35ad928f8c0b182e0ce9457e5a33e0450da886f91b59637521fd72dc624
4
- data.tar.gz: d6b4c4844b91c6cfd8122422b37ebe567bb9a2be9557b3ceb3b3b266b599ca79
3
+ metadata.gz: 4472049678531606c70c32415b9fde26f897fae21ffdf4099b01fd301f1dff57
4
+ data.tar.gz: 305f69f3690a8a6b5468a57f7a5af8142fa90bf24a72499dc9f06094e007c1b6
5
5
  SHA512:
6
- metadata.gz: 22b535ce7535ed5eb746c51f08794aa399f55be9e3b2e7ce83f1a38650f23902808245fe4162c033d3024a21dd1a1dd452e341eb4de34ebe9b2872b71ea17e59
7
- data.tar.gz: dc9ec1c71c2509dcabe92da46b3432d2b2c1e42b313a5dc274afc665bf739dd6b6582634ec5c5367b5dc6835cdbb387840344c20405249e304d8b43681ee9ac0
6
+ metadata.gz: af09bca7283a90b7644926048e178778778df5f333998a43719b37353fc5d7fd396212d8a65fcc3644c203189ab7cef6e5799b360f83caff08b879d9aef70dfa
7
+ data.tar.gz: 314cfdee1be67a5fa1fe67211081973c8f52999cd4915440c28ecd0a76d880b73051d67dcb73068b3155e731d668bc6e0060a47eb4fd0394f8b254e56a3668c7
data/Puppetfile CHANGED
@@ -33,7 +33,7 @@ mod 'puppetlabs-ruby_plugin_helper', '0.1.0'
33
33
  mod 'puppetlabs-aws_inventory', '0.5.0'
34
34
  mod 'puppetlabs-azure_inventory', '0.3.0'
35
35
  mod 'puppetlabs-gcloud_inventory', '0.1.1'
36
- mod 'puppetlabs-pkcs7', '0.1.0'
36
+ mod 'puppetlabs-pkcs7', '0.1.1'
37
37
  mod 'puppetlabs-terraform', '0.5.0'
38
38
  mod 'puppetlabs-vault', '0.3.0'
39
39
  mod 'puppetlabs-yaml', '0.2.0'
@@ -11,12 +11,13 @@ Puppet::DataTypes.create_type('ResourceInstance') do
11
11
  'events' => Optional[Array[Hash[String[1], Data]]]
12
12
  },
13
13
  functions => {
14
- add_event => Callable[[Hash[String[1], Data]], [Hash[String[1], Data]]],
14
+ add_event => Callable[[Hash[String[1], Data]], Array[Hash[String[1], Data]]],
15
15
  set_state => Callable[[Hash[String[1], Data]], Hash[String[1], Data]],
16
16
  overwrite_state => Callable[[Hash[String[1], Data]], Hash[String[1], Data]],
17
17
  set_desired_state => Callable[[Hash[String[1], Data]], Hash[String[1], Data]],
18
18
  overwrite_desired_state => Callable[[Hash[String[1], Data]], Hash[String[1], Data]],
19
- reference => Callable[[], String]
19
+ reference => Callable[[], String],
20
+ '[]' => Callable[[String[1]], Data]
20
21
  }
21
22
  PUPPET
22
23
 
@@ -25,6 +25,7 @@ Puppet::Functions.create_function(:add_facts) do
25
25
 
26
26
  inventory = Puppet.lookup(:bolt_inventory)
27
27
  executor = Puppet.lookup(:bolt_executor)
28
+ # Send Analytics Report
28
29
  executor.report_function_call(self.class.name)
29
30
 
30
31
  inventory.add_facts(target, facts)
@@ -29,6 +29,7 @@ Puppet::Functions.create_function(:add_to_group) do
29
29
 
30
30
  inventory = Puppet.lookup(:bolt_inventory)
31
31
  executor = Puppet.lookup(:bolt_executor)
32
+ # Send Analytics Report
32
33
  executor.report_function_call(self.class.name)
33
34
 
34
35
  inventory.add_to_group(inventory.get_targets(targets), group)
@@ -3,7 +3,7 @@
3
3
  require 'bolt/task'
4
4
 
5
5
  # Installs the `puppet-agent` package on targets if needed, then collects facts,
6
- # including any custom facts found in Bolt's modulepath. The package is
6
+ # including any custom facts found in Bolt's module path. The package is
7
7
  # installed using either the configured plugin or the `task` plugin with the
8
8
  # `puppet_agent::install` task.
9
9
  #
@@ -37,6 +37,7 @@ Puppet::Functions.create_function(:catch_errors) do
37
37
  end
38
38
 
39
39
  executor = Puppet.lookup(:bolt_executor)
40
+ # Send Analytics Report
40
41
  executor.report_function_call(self.class.name)
41
42
 
42
43
  begin
@@ -17,6 +17,7 @@ Puppet::Functions.create_function(:facts) do
17
17
  inventory = Puppet.lookup(:bolt_inventory)
18
18
  # Bolt executor not expected when invoked from apply block
19
19
  executor = Puppet.lookup(:bolt_executor) { nil }
20
+ # Send Analytics Report
20
21
  executor&.report_function_call(self.class.name)
21
22
 
22
23
  inventory.facts(target)
@@ -40,6 +40,7 @@ Puppet::Functions.create_function(:fail_plan) do
40
40
  end
41
41
 
42
42
  executor = Puppet.lookup(:bolt_executor)
43
+ # Send Analytics Report
43
44
  executor.report_function_call(self.class.name)
44
45
 
45
46
  raise Bolt::PlanFailure.new(msg, kind || 'bolt/plan-failure', details, issue_code)
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'bolt/task'
4
4
 
5
- # Query the state of resources on a list of targets using resource definitions in Bolt's modulepath.
5
+ # Query the state of resources on a list of targets using resource definitions in Bolt's module path.
6
6
  # The results are returned as a list of hashes representing each resource.
7
7
  #
8
8
  # Requires the Puppet Agent be installed on the target, which can be accomplished with apply_prep
@@ -58,6 +58,7 @@ Puppet::Functions.create_function(:get_resources) do
58
58
  end
59
59
  end
60
60
 
61
+ # Send Analytics Report
61
62
  executor.report_function_call(self.class.name)
62
63
 
63
64
  targets = inventory.get_targets(target_spec)
@@ -21,6 +21,7 @@ Puppet::Functions.create_function(:get_target) do
21
21
  inventory = Puppet.lookup(:bolt_inventory)
22
22
  # Bolt executor not expected when invoked from apply block
23
23
  executor = Puppet.lookup(:bolt_executor) { nil }
24
+ # Send Analytics Report
24
25
  executor&.report_function_call(self.class.name)
25
26
 
26
27
  unless inventory.version > 1
@@ -27,6 +27,7 @@ Puppet::Functions.create_function(:get_targets) do
27
27
  inventory = Puppet.lookup(:bolt_inventory)
28
28
  # Bolt executor not expected when invoked from apply block
29
29
  executor = Puppet.lookup(:bolt_executor) { nil }
30
+ # Send Analytics Report
30
31
  executor&.report_function_call(self.class.name)
31
32
 
32
33
  inventory.get_targets(names)
@@ -20,6 +20,7 @@ Puppet::Functions.create_function(:puppetdb_fact) do
20
20
  puppetdb_client = Puppet.lookup(:bolt_pdb_client)
21
21
  # Bolt executor not expected when invoked from apply block
22
22
  executor = Puppet.lookup(:bolt_executor) { nil }
23
+ # Send Analytics Report
23
24
  executor&.report_function_call(self.class.name)
24
25
 
25
26
  puppetdb_client.facts_for_node(certnames)
@@ -22,6 +22,7 @@ Puppet::Functions.create_function(:puppetdb_query) do
22
22
  puppetdb_client = Puppet.lookup(:bolt_pdb_client)
23
23
  # Bolt executor not expected when invoked from apply block
24
24
  executor = Puppet.lookup(:bolt_executor) { nil }
25
+ # Send Analytics Report
25
26
  executor&.report_function_call(self.class.name)
26
27
 
27
28
  puppetdb_client.make_query(query)
@@ -31,6 +31,7 @@ Puppet::Functions.create_function(:remove_from_group) do
31
31
 
32
32
  inventory = Puppet.lookup(:bolt_inventory)
33
33
  executor = Puppet.lookup(:bolt_executor)
34
+ # Send Analytics Report
34
35
  executor.report_function_call(self.class.name)
35
36
 
36
37
  inventory.remove_from_group(inventory.get_targets(target), group)
@@ -33,6 +33,7 @@ Puppet::Functions.create_function(:resolve_references) do
33
33
  end
34
34
 
35
35
  executor = Puppet.lookup(:bolt_executor)
36
+ # Send Analytics Report
36
37
  executor.report_function_call(self.class.name)
37
38
 
38
39
  plugins = Puppet.lookup(:bolt_inventory).plugins
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Lookup a resource in the target's data.
4
+ #
5
+ # For more information about resources see [the
6
+ # documentation](https://puppet.com/docs/puppet/latest/lang_resources.html).
7
+ #
8
+ # > **Note:** The `ResourceInstance` data type is under active development and is subject to
9
+ # change. You can read more about the data type in the [experimental features
10
+ # documentation](experimental_features.md#resourceinstance-data-type).
11
+ Puppet::Functions.create_function(:resource) do
12
+ # Lookup a resource in the target's data.
13
+ # @param target The Target object to add resources to. See {get_targets}.
14
+ # @param type The type of the resource
15
+ # @param title The title of the resource
16
+ # @return The ResourceInstance if found, or Undef
17
+ # @example Get the openssl package resource
18
+ # $target.apply_prep
19
+ # $resources = $target.get_resources(Package).first['resources']
20
+ # $target.set_resources($resources)
21
+ # $openssl = $target.resource('Package', 'openssl')
22
+ dispatch :resource do
23
+ param 'Target', :target
24
+ param 'Type[Resource]', :type
25
+ param 'String[1]', :title
26
+ return_type 'Optional[ResourceInstance]'
27
+ end
28
+
29
+ # Lookup a resource in the target's data, referring to resource as a string
30
+ # @param target The Target object to add resources to. See {get_targets}.
31
+ # @param type The type of the resource
32
+ # @param title The title of the resource
33
+ # @return The ResourceInstance if found, or Undef
34
+ dispatch :resource_from_string do
35
+ param 'Target', :target
36
+ param 'String[1]', :type
37
+ param 'String[1]', :title
38
+ return_type 'Optional[ResourceInstance]'
39
+ end
40
+
41
+ def resource(target, type, title)
42
+ inventory = Puppet.lookup(:bolt_inventory)
43
+ executor = Puppet.lookup(:bolt_executor) { nil }
44
+ # Send Analytics Report
45
+ executor&.report_function_call(self.class.name)
46
+
47
+ inventory.resource(target, type, title)
48
+ end
49
+
50
+ def resource_from_string(target, type, title)
51
+ resource(target, type, title)
52
+ end
53
+ end
@@ -57,6 +57,7 @@ Puppet::Functions.create_function(:run_command) do
57
57
  executor = Puppet.lookup(:bolt_executor)
58
58
  inventory = Puppet.lookup(:bolt_inventory)
59
59
 
60
+ # Send Analytics Report
60
61
  executor.report_function_call(self.class.name)
61
62
 
62
63
  # Ensure that given targets are all Target instances
@@ -64,10 +64,11 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
64
64
  # Bolt calls this function internally to trigger plans from the CLI. We
65
65
  # don't want to count those invocations.
66
66
  unless options[:bolt_api_call]
67
+ # Send Analytics Report
67
68
  executor.report_function_call(self.class.name)
68
69
  end
69
70
 
70
- # Report bundled content, this should capture plans run from both CLI and Plans
71
+ # Send Analytics Report for bundled content, this should capture plans run from both CLI and Plans
71
72
  executor.report_bundled_content('Plan', plan_name)
72
73
 
73
74
  loaders = closure_scope.compiler.loaders
@@ -109,6 +110,15 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
109
110
  end
110
111
  end
111
112
 
113
+ # Wrap Sensitive parameters for plans that are run from the CLI, as it's impossible to pass
114
+ # a Sensitive value that way. We don't do this for plans run from the run_plan function, as
115
+ # it can receive Sensitive values as arguments.
116
+ # This should only happen after expanding target params, otherwise things will blow up if
117
+ # the targets are wrapped as Sensitive. Hopefully nobody does that, though...
118
+ if options[:bolt_api_call]
119
+ params = wrap_sensitive_parameters(params, closure.parameters)
120
+ end
121
+
112
122
  # wrap plan execution in logging messages
113
123
  executor.log_plan(plan_name) do
114
124
  result = nil
@@ -169,6 +179,62 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
169
179
  end
170
180
  end
171
181
 
182
+ # Wrap any Sensitive parameters in the Sensitive wrapper type, unless they are already
183
+ # wrapped as Sensitive. This will also raise a helpful warning if the type expression
184
+ # is a complex data type using Sensitive, as we don't handle those cases.
185
+ def wrap_sensitive_parameters(params, param_models)
186
+ models = param_models.each_with_object({}) { |param, acc| acc[param.name] = param }
187
+
188
+ params.each_with_object({}) do |(name, value), acc|
189
+ model = models[name]
190
+
191
+ # Parameters passed to a plan that the plan is not expecting don't have a model,
192
+ # so keep the parameter as-is.
193
+ if model.nil?
194
+ acc[name] = value
195
+ elsif sensitive_type?(model.type_expr)
196
+ acc[name] = Puppet::Pops::Types::PSensitiveType::Sensitive.new(value)
197
+ else
198
+ if model.type_expr.to_s.include?('Sensitive')
199
+ # Include the location for regular plans. YAML plans don't have this info, so
200
+ # the location will be suppressed.
201
+ file = defined?(model.file) ? model.file : :default
202
+ line = defined?(model.line) ? model.line : :default
203
+
204
+ Puppet.warn_once(
205
+ 'unsupported_sensitive_type',
206
+ name,
207
+ "Parameter '#{name}' is a complex type using Sensitive, unable to automatically wrap as Sensitive",
208
+ file,
209
+ line
210
+ )
211
+ end
212
+
213
+ acc[name] = value
214
+ end
215
+ end
216
+ end
217
+
218
+ # Whether the type is a supported Sensitive type. We only support wrapping parameterized
219
+ # and non-parameterized Sensitive types (e.g. Sensitive, Sensitive[String])
220
+ def sensitive_type?(type_expr)
221
+ # Parameterized Sensitive type (e.g. Sensitive[String])
222
+ # left_expr is defined whenever the type is parameterized. If this is a parameterized
223
+ # Sensitive type, then we check the cased_value, which is the stringified version of
224
+ # the left expression's type.
225
+ (defined?(type_expr.left_expr) && type_expr.left_expr.cased_value == 'Sensitive') ||
226
+ # Non-parameterized Sensitive type (Sensitive)
227
+ # cased_value is defined whenever the type is non-parameterized. If the type expression
228
+ # defines cased_value, then this is a simple type and we just need to check that it's
229
+ # Sensitive.
230
+ (defined?(type_expr.cased_value) && type_expr.cased_value == 'Sensitive') ||
231
+ # Sensitive type from YAML plans
232
+ # Type expressions from YAML plans are a different class than those from regular plans.
233
+ # As long as the type expression is PSensitiveType we can be sure that the type is
234
+ # either a parameterized or non-parameterized Sensitive type.
235
+ type_expr.instance_of?(Puppet::Pops::Types::PSensitiveType)
236
+ end
237
+
172
238
  def targets_to_param(targets, params, param_types)
173
239
  nodes_param = param_types.include?('nodes')
174
240
  targets_param = param_types['targets']&.any? { |p| p.match?(/TargetSpec/) }
@@ -64,6 +64,7 @@ Puppet::Functions.create_function(:run_script, Puppet::Functions::InternalFuncti
64
64
  executor = Puppet.lookup(:bolt_executor)
65
65
  inventory = Puppet.lookup(:bolt_inventory)
66
66
 
67
+ # Send Analytics Report
67
68
  executor.report_function_call(self.class.name)
68
69
 
69
70
  found = Puppet::Parser::Files.find_file(script, scope.compiler.environment)
@@ -64,10 +64,11 @@ Puppet::Functions.create_function(:run_task) do
64
64
  # Bolt calls this function internally to trigger tasks from the CLI. We
65
65
  # don't want to count those invocations.
66
66
  unless options[:bolt_api_call]
67
+ # Send Analytics Report
67
68
  executor.report_function_call(self.class.name)
68
69
  end
69
70
 
70
- # Report bundled content, this should capture tasks run from both CLI and Plans
71
+ # Report Analytics for bundled content, this should capture tasks run from both CLI and Plans
71
72
  executor.report_bundled_content('Task', task_name)
72
73
 
73
74
  # Ensure that given targets are all Target instances
@@ -88,8 +89,10 @@ Puppet::Functions.create_function(:run_task) do
88
89
 
89
90
  task = Bolt::Task.from_task_signature(task_signature)
90
91
 
91
- # Set the default value for any params that have one and were not provided
92
- params = task.parameter_defaults.merge(params)
92
+ # Set the default value for any params that have one and were not provided or are undef
93
+ params = task.parameter_defaults.merge(params) do |_, default, passed|
94
+ passed.nil? ? default : passed
95
+ end
93
96
 
94
97
  task_signature.runnable_with?(params) do |mismatch_message|
95
98
  raise with_stack(:TYPE_MISMATCH, mismatch_message)
@@ -124,7 +124,10 @@ Puppet::Functions.create_function(:run_task_with) do
124
124
  # If parameters are mismatched, create a failing result for the target that will later
125
125
  # be added to the ResultSet.
126
126
  unless pcp_only
127
- params = task.parameter_defaults.merge(params)
127
+ # Set the default value for any params that have one and were not provided or are undef
128
+ params = task.parameter_defaults.merge(params) do |_, default, passed|
129
+ passed.nil? ? default : passed
130
+ end
128
131
 
129
132
  type_match = task_signature.runnable_with?(params) do |mismatch_message|
130
133
  exception = with_stack(:TYPE_MISMATCH, mismatch_message)
@@ -157,7 +160,10 @@ Puppet::Functions.create_function(:run_task_with) do
157
160
  end
158
161
  end
159
162
 
160
- mapping[target] = task.parameter_defaults.merge(params)
163
+ # Set the default value for any params that have one and were not provided or are undef
164
+ mapping[target] = task.parameter_defaults.merge(params) do |_, default, passed|
165
+ passed.nil? ? default : passed
166
+ end
161
167
  end
162
168
 
163
169
  # Add a noop parameter if the function was called with the noop metaparameter.
@@ -33,6 +33,7 @@ Puppet::Functions.create_function(:set_config) do
33
33
 
34
34
  inventory = Puppet.lookup(:bolt_inventory)
35
35
  executor = Puppet.lookup(:bolt_executor)
36
+ # Send Analytics Report
36
37
  executor.report_function_call(self.class.name)
37
38
 
38
39
  unless inventory.version > 1
@@ -33,6 +33,7 @@ Puppet::Functions.create_function(:set_feature) do
33
33
 
34
34
  inventory = Puppet.lookup(:bolt_inventory)
35
35
  executor = Puppet.lookup(:bolt_executor)
36
+ # Send Analytics Report
36
37
  executor.report_function_call(self.class.name)
37
38
 
38
39
  inventory.set_feature(target, feature, value)
@@ -14,26 +14,61 @@ require 'bolt/error'
14
14
  #
15
15
  # > **Note:** Not available in apply block
16
16
  Puppet::Functions.create_function(:set_resources) do
17
- # Set multiple resources
18
- # @param target The `Target` object to add resources to. See {get_targets}.
19
- # @param resources The resources to set on the target.
20
- # @return The added `ResourceInstance` objects.
21
- # @example Add multiple resources to a target with an array of `ResourceInstance` objects.
22
- # $resource1 = ResourceInstance.new(
17
+ # Set a single resource from a data hash.
18
+ # @param target The `Target` object to add a resource to. See {get_targets}.
19
+ # @param resource The resource data hash used to set a resource on the target.
20
+ # @return An array with the added `ResourceInstance` object.
21
+ # @example Add a resource to a target from a data hash.
22
+ # $resource_hash = {
23
+ # 'type' => File,
24
+ # 'title' => '/etc/puppetlabs',
25
+ # 'state' => { 'ensure' => 'present' }
26
+ # }
27
+ #
28
+ # $target.set_resources($resource_hash)
29
+ dispatch :set_single_resource_from_hash do
30
+ param 'Target', :target
31
+ param 'Hash', :resource
32
+ return_type 'Array[ResourceInstance]'
33
+ end
34
+
35
+ # Set a single resource from a `ResourceInstance` object
36
+ # @param target The `Target` object to add a resource to. See {get_targets}.
37
+ # @param resource The `ResourceInstance` object to set on the target.
38
+ # @return An array with the added `ResourceInstance` object.
39
+ # @example Add a resource to a target from a `ResourceInstance` object.
40
+ # $resource_instance = ResourceInstance.new(
23
41
  # 'target' => $target,
24
- # 'type' => 'file',
42
+ # 'type' => File,
25
43
  # 'title' => '/etc/puppetlabs',
26
44
  # 'state' => { 'ensure' => 'present' }
27
45
  # )
28
- # $resource2 = ResourceInstance.new(
29
- # 'target' => $target,
30
- # 'type' => 'package',
31
- # 'title' => 'openssl',
32
- # 'state' => { 'ensure' => 'installed' }
33
- # )
34
- # $target.set_resources([$resource1, $resource2])
46
+ #
47
+ # $target.set_resources($resource_instance)
48
+ dispatch :set_single_resource_from_object do
49
+ param 'Target', :target
50
+ param 'ResourceInstance', :resource
51
+ return_type 'Array[ResourceInstance]'
52
+ end
53
+
54
+ # Set multiple resources from an array of data hashes and `ResourceInstance` objects.
55
+ # @param target The `Target` object to add resources to. See {get_targets}.
56
+ # @param resources The resource data hashes and `ResourceInstance` objects to set on the target.
57
+ # @return An array of the added `ResourceInstance` objects.
58
+ # @example Add resources from resource data hashes returned from an apply block.
59
+ # $apply_results = apply($targets) {
60
+ # File { '/etc/puppetlabs':
61
+ # ensure => present
62
+ # }
63
+ # Package { 'openssl':
64
+ # ensure => installed
65
+ # }
66
+ # }
67
+ #
68
+ # $apply_results.each |$result| {
69
+ # $result.target.set_resources($result.report['resource_statuses'].values)
70
+ # }
35
71
  # @example Add resources retrieved with [`get_resources`](#get_resources) to a target.
36
- # $target.apply_prep
37
72
  # $resources = $target.get_resources(Package).first['resources']
38
73
  # $target.set_resources($resources)
39
74
  dispatch :set_resources do
@@ -42,21 +77,12 @@ Puppet::Functions.create_function(:set_resources) do
42
77
  return_type 'Array[ResourceInstance]'
43
78
  end
44
79
 
45
- # Set a single resource
46
- # @param target The `Target` object to add resources to. See {get_targets}.
47
- # @param resource The resource to set on the target.
48
- # @return The added `ResourceInstance` object.
49
- # @example Add a single resource to a target with a resource data hash.
50
- # $resource = {
51
- # 'type' => 'file',
52
- # 'title' => '/etc/puppetlabs',
53
- # 'state' => { 'ensure' => 'present' }
54
- # }
55
- # $target.set_resources($resource)
56
- dispatch :set_resource do
57
- param 'Target', :target
58
- param 'Variant[Hash, ResourceInstance]', :resource
59
- return_type 'Array[ResourceInstance]'
80
+ def set_single_resource_from_hash(target, resource)
81
+ set_resources(target, [resource])
82
+ end
83
+
84
+ def set_single_resource_from_object(target, resource)
85
+ set_resources(target, [resource])
60
86
  end
61
87
 
62
88
  def set_resources(target, resources)
@@ -68,11 +94,9 @@ Puppet::Functions.create_function(:set_resources) do
68
94
  )
69
95
  end
70
96
 
97
+ # Send Analytics Report
98
+ Puppet.lookup(:bolt_executor).report_function_call(self.class.name)
71
99
  inventory = Puppet.lookup(:bolt_inventory)
72
- executor = Puppet.lookup(:bolt_executor)
73
- executor.report_function_call(self.class.name)
74
-
75
- inventory_target = inventory.get_target(target)
76
100
 
77
101
  resources.uniq.map do |resource|
78
102
  if resource.is_a?(Hash)
@@ -81,15 +105,18 @@ Puppet::Functions.create_function(:set_resources) do
81
105
  resource_target = if resource.key?('target')
82
106
  inventory.get_target(resource['target'])
83
107
  else
84
- inventory_target
108
+ target
85
109
  end
86
110
 
87
111
  # Observed state from get_resources() is under the 'parameters' key
88
112
  resource_state = resource['state'] || resource['parameters']
89
113
 
114
+ # Type from apply results is under the 'resource_type' key
115
+ resource_type = resource['type'] || resource['resource_type']
116
+
90
117
  init_hash = {
91
118
  'target' => resource_target,
92
- 'type' => resource['type'],
119
+ 'type' => resource_type,
93
120
  'title' => resource['title'],
94
121
  'state' => resource_state,
95
122
  'desired_state' => resource['desired_state'],
@@ -105,18 +132,14 @@ Puppet::Functions.create_function(:set_resources) do
105
132
  resource = call_function('new', type, init_hash)
106
133
  end
107
134
 
108
- unless resource.target == inventory_target
135
+ unless resource.target == target
109
136
  file, line = Puppet::Pops::PuppetStack.top_of_stack
110
137
  raise Bolt::ValidationError, "Cannot set resource #{resource.reference} for target "\
111
- "#{resource.target} on target #{inventory_target}. "\
138
+ "#{resource.target} on target #{target}. "\
112
139
  "#{Puppet::Util::Errors.error_location(file, line)}"
113
140
  end
114
141
 
115
- inventory_target.set_resource(resource)
142
+ target.set_resource(resource)
116
143
  end
117
144
  end
118
-
119
- def set_resource(target, resource)
120
- set_resources(target, [resource])
121
- end
122
145
  end