bolt 2.6.0 → 2.11.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +4 -3
  3. data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +2 -0
  4. data/bolt-modules/boltlib/lib/puppet/datatypes/resourceinstance.rb +27 -0
  5. data/bolt-modules/boltlib/lib/puppet/datatypes/result.rb +2 -0
  6. data/bolt-modules/boltlib/lib/puppet/datatypes/resultset.rb +2 -0
  7. data/bolt-modules/boltlib/lib/puppet/datatypes/target.rb +4 -3
  8. data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +1 -1
  9. data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +192 -0
  10. data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +122 -0
  11. data/bolt-modules/boltlib/types/planresult.pp +12 -1
  12. data/bolt-modules/file/lib/puppet/functions/file/exists.rb +3 -1
  13. data/bolt-modules/file/lib/puppet/functions/file/join.rb +1 -1
  14. data/bolt-modules/file/lib/puppet/functions/file/read.rb +2 -1
  15. data/bolt-modules/file/lib/puppet/functions/file/readable.rb +3 -1
  16. data/bolt-modules/file/lib/puppet/functions/file/write.rb +3 -1
  17. data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +43 -0
  18. data/lib/bolt/analytics.rb +1 -1
  19. data/lib/bolt/applicator.rb +3 -2
  20. data/lib/bolt/apply_inventory.rb +1 -1
  21. data/lib/bolt/apply_result.rb +1 -1
  22. data/lib/bolt/apply_target.rb +11 -2
  23. data/lib/bolt/bolt_option_parser.rb +27 -7
  24. data/lib/bolt/catalog.rb +32 -3
  25. data/lib/bolt/cli.rb +52 -22
  26. data/lib/bolt/config.rb +51 -27
  27. data/lib/bolt/config/transport/base.rb +3 -3
  28. data/lib/bolt/config/transport/docker.rb +7 -1
  29. data/lib/bolt/config/transport/local.rb +9 -1
  30. data/lib/bolt/config/transport/orch.rb +4 -2
  31. data/lib/bolt/config/transport/remote.rb +2 -0
  32. data/lib/bolt/config/transport/ssh.rb +81 -3
  33. data/lib/bolt/config/transport/winrm.rb +6 -1
  34. data/lib/bolt/executor.rb +38 -0
  35. data/lib/bolt/inventory.rb +2 -1
  36. data/lib/bolt/inventory/group.rb +1 -0
  37. data/lib/bolt/inventory/inventory.rb +9 -0
  38. data/lib/bolt/inventory/target.rb +17 -1
  39. data/lib/bolt/node/output.rb +1 -1
  40. data/lib/bolt/outputter/human.rb +5 -4
  41. data/lib/bolt/outputter/json.rb +1 -1
  42. data/lib/bolt/pal.rb +32 -14
  43. data/lib/bolt/pal/yaml_plan.rb +1 -0
  44. data/lib/bolt/plugin.rb +14 -8
  45. data/lib/bolt/plugin/env_var.rb +2 -1
  46. data/lib/bolt/plugin/module.rb +40 -7
  47. data/lib/bolt/plugin/prompt.rb +1 -1
  48. data/lib/bolt/plugin/puppetdb.rb +5 -2
  49. data/lib/bolt/project.rb +135 -0
  50. data/lib/bolt/puppetdb/config.rb +16 -28
  51. data/lib/bolt/rerun.rb +1 -1
  52. data/lib/bolt/resource_instance.rb +126 -0
  53. data/lib/bolt/result.rb +46 -23
  54. data/lib/bolt/result_set.rb +2 -5
  55. data/lib/bolt/secret.rb +20 -4
  56. data/lib/bolt/shell/bash.rb +27 -14
  57. data/lib/bolt/shell/bash/tmpdir.rb +1 -1
  58. data/lib/bolt/shell/powershell.rb +43 -15
  59. data/lib/bolt/shell/powershell/snippets.rb +1 -1
  60. data/lib/bolt/target.rb +18 -2
  61. data/lib/bolt/transport/base.rb +24 -8
  62. data/lib/bolt/transport/docker.rb +3 -3
  63. data/lib/bolt/transport/docker/connection.rb +11 -7
  64. data/lib/bolt/transport/local/connection.rb +13 -7
  65. data/lib/bolt/transport/orch.rb +5 -1
  66. data/lib/bolt/transport/ssh.rb +6 -2
  67. data/lib/bolt/transport/ssh/connection.rb +26 -1
  68. data/lib/bolt/transport/ssh/exec_connection.rb +110 -0
  69. data/lib/bolt/transport/winrm/connection.rb +10 -2
  70. data/lib/bolt/version.rb +1 -1
  71. data/lib/bolt_server/pe/pal.rb +1 -38
  72. data/lib/bolt_server/transport_app.rb +7 -7
  73. data/lib/bolt_spec/bolt_context.rb +3 -6
  74. data/lib/bolt_spec/plans.rb +78 -8
  75. data/lib/bolt_spec/plans/action_stubs.rb +37 -7
  76. data/lib/bolt_spec/plans/action_stubs/plan_stub.rb +55 -0
  77. data/lib/bolt_spec/plans/mock_executor.rb +62 -2
  78. data/lib/bolt_spec/run.rb +10 -13
  79. metadata +26 -7
  80. data/lib/bolt/boltdir.rb +0 -54
  81. data/lib/bolt/plugin/pkcs7.rb +0 -104
  82. data/lib/bolt/secret/base.rb +0 -41
@@ -7,11 +7,15 @@ module Bolt
7
7
  class Config
8
8
  module Transport
9
9
  class WinRM < Base
10
+ # NOTE: All transport configuration options should have a corresponding schema definition
11
+ # in schemas/bolt-transport-definitions.json
10
12
  OPTIONS = {
11
13
  "basic-auth-only" => { type: TrueClass,
12
14
  desc: "Force basic authentication. This option is only available when using SSL." },
13
15
  "cacert" => { type: String,
14
16
  desc: "The path to the CA certificate." },
17
+ "cleanup" => { type: TrueClass,
18
+ desc: "Whether to clean up temporary files created on targets." },
15
19
  "connect-timeout" => { type: Integer,
16
20
  desc: "How long Bolt should wait when establishing connections." },
17
21
  "extensions" => { type: Array,
@@ -53,6 +57,7 @@ module Bolt
53
57
 
54
58
  DEFAULTS = {
55
59
  "basic-auth-only" => false,
60
+ "cleanup" => true,
56
61
  "connect-timeout" => 10,
57
62
  "ssl" => true,
58
63
  "ssl-verify" => true,
@@ -68,7 +73,7 @@ module Bolt
68
73
  end
69
74
 
70
75
  if @config['cacert']
71
- @config['cacert'] = File.expand_path(@config['cacert'], @boltdir)
76
+ @config['cacert'] = File.expand_path(@config['cacert'], @project)
72
77
  Bolt::Util.validate_file('cacert', @config['cacert'])
73
78
  end
74
79
  end
@@ -278,6 +278,22 @@ module Bolt
278
278
  end
279
279
  end
280
280
 
281
+ def run_task_with(target_mapping, task, options = {})
282
+ targets = target_mapping.keys
283
+ description = options.fetch(:description, "task #{task.name}")
284
+
285
+ log_action(description, targets) do
286
+ options[:run_as] = run_as if run_as && !options.key?(:run_as)
287
+ target_mapping.each_value { |arguments| arguments['_task'] = task.name }
288
+
289
+ batch_execute(targets) do |transport, batch|
290
+ with_node_logging("Running task #{task.name}'", batch) do
291
+ transport.batch_task_with(batch, task, target_mapping, options, &method(:publish_event))
292
+ end
293
+ end
294
+ end
295
+ end
296
+
281
297
  def upload_file(targets, source, destination, options = {})
282
298
  description = options.fetch(:description, "file upload from #{source} to #{destination}")
283
299
  log_action(description, targets) do
@@ -291,6 +307,10 @@ module Bolt
291
307
  end
292
308
  end
293
309
 
310
+ def run_plan(scope, plan, params)
311
+ plan.call_by_name_with_scope(scope, params, true)
312
+ end
313
+
294
314
  class TimeoutError < RuntimeError; end
295
315
 
296
316
  def wait_until_available(targets,
@@ -326,6 +346,24 @@ module Bolt
326
346
  end
327
347
  end
328
348
 
349
+ def prompt(prompt, options)
350
+ unless STDIN.tty?
351
+ raise Bolt::Error.new('STDIN is not a tty, unable to prompt', 'bolt/no-tty-error')
352
+ end
353
+
354
+ STDERR.print("#{prompt}: ")
355
+
356
+ value = if options[:sensitive]
357
+ STDIN.noecho(&:gets).to_s.chomp
358
+ else
359
+ STDIN.gets.to_s.chomp
360
+ end
361
+
362
+ STDERR.puts if options[:sensitive]
363
+
364
+ value
365
+ end
366
+
329
367
  # Plan context doesn't make sense for most transports but it is tightly
330
368
  # coupled with the orchestrator transport since the transport behaves
331
369
  # differently when a plan is running. In order to limit how much this
@@ -15,6 +15,7 @@ module Bolt
15
15
 
16
16
  class ValidationError < Bolt::Error
17
17
  attr_accessor :path
18
+
18
19
  def initialize(message, offending_group)
19
20
  super(message, 'bolt.inventory/validation-error')
20
21
  @_message = message
@@ -83,7 +84,7 @@ module Bolt
83
84
 
84
85
  def self.empty
85
86
  config = Bolt::Config.default
86
- plugins = Bolt::Plugin.setup(config, nil, nil, Bolt::Analytics::NoopClient)
87
+ plugins = Bolt::Plugin.setup(config, nil)
87
88
 
88
89
  create_version({}, config.transport, config.transports, plugins)
89
90
  end
@@ -12,6 +12,7 @@ module Bolt
12
12
  # Regex used to validate group names and target aliases.
13
13
  NAME_REGEX = /\A[a-z0-9_][a-z0-9_-]*\Z/.freeze
14
14
 
15
+ # NOTE: All keys should have a corresponding schema property in schemas/bolt-inventory.schema.json
15
16
  DATA_KEYS = %w[config facts vars features plugin_hooks].freeze
16
17
  TARGET_KEYS = DATA_KEYS + %w[name alias uri]
17
18
  GROUP_KEYS = DATA_KEYS + %w[name groups targets]
@@ -7,6 +7,7 @@ module Bolt
7
7
  class Inventory
8
8
  class Inventory
9
9
  attr_reader :targets, :plugins, :config, :transport
10
+
10
11
  class WildcardError < Bolt::Error
11
12
  def initialize(target)
12
13
  super("Found 0 targets matching wildcard pattern #{target}", 'bolt.inventory/wildcard-error')
@@ -50,6 +51,10 @@ module Bolt
50
51
  @group_lookup.keys
51
52
  end
52
53
 
54
+ def group_names_for(target_name)
55
+ group_data_for(target_name).fetch('groups', [])
56
+ end
57
+
53
58
  def target_names
54
59
  @groups.all_targets
55
60
  end
@@ -314,6 +319,10 @@ module Bolt
314
319
  def target_config(target)
315
320
  @targets[target.name].config
316
321
  end
322
+
323
+ def resources(target)
324
+ @targets[target.name].resources
325
+ end
317
326
  end
318
327
  end
319
328
  end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'bolt/resource_instance'
4
+
3
5
  module Bolt
4
6
  class Inventory
5
7
  # This class represents the active state of a target within the inventory.
6
8
  class Target
7
- attr_reader :name, :uri, :safe_name, :target_alias
9
+ attr_reader :name, :uri, :safe_name, :target_alias, :resources
8
10
 
9
11
  def initialize(target_data, inventory)
10
12
  unless target_data['name'] || target_data['uri']
@@ -36,12 +38,26 @@ module Bolt
36
38
  # When alias is specified in a plan, the key will be `target_alias`, when
37
39
  # alias is specified in inventory the key will be `alias`.
38
40
  @target_alias = target_data['target_alias'] || target_data['alias'] || []
41
+ @resources = {}
39
42
 
40
43
  @inventory = inventory
41
44
 
42
45
  validate
43
46
  end
44
47
 
48
+ # rubocop:disable Naming/AccessorMethodName
49
+ def set_resource(resource)
50
+ if (existing_resource = resources[resource.reference])
51
+ existing_resource.overwrite_state(resource.state)
52
+ existing_resource.overwrite_desired_state(resource.desired_state)
53
+ existing_resource.events = existing_resource.events + resource.events
54
+ existing_resource
55
+ else
56
+ @resources[resource.reference] = resource
57
+ end
58
+ end
59
+ # rubocop:enable Naming/AccessorMethodName
60
+
45
61
  def vars
46
62
  group_cache['vars'].merge(@vars)
47
63
  end
@@ -12,7 +12,7 @@ module Bolt
12
12
  def initialize
13
13
  @stdout = StringIO.new
14
14
  @stderr = StringIO.new
15
- @exit_code = 'unkown'
15
+ @exit_code = 'unknown'
16
16
  end
17
17
  end
18
18
  end
@@ -107,13 +107,14 @@ module Bolt
107
107
 
108
108
  # Use special handling if the result looks like a command or script result
109
109
  if result.generic_value.keys == %w[stdout stderr exit_code]
110
- unless result['stdout'].strip.empty?
110
+ safe_value = result.safe_value
111
+ unless safe_value['stdout'].strip.empty?
111
112
  @stream.puts(indent(2, "STDOUT:"))
112
- @stream.puts(indent(4, result['stdout']))
113
+ @stream.puts(indent(4, safe_value['stdout']))
113
114
  end
114
- unless result['stderr'].strip.empty?
115
+ unless safe_value['stderr'].strip.empty?
115
116
  @stream.puts(indent(2, "STDERR:"))
116
- @stream.puts(indent(4, result['stderr']))
117
+ @stream.puts(indent(4, safe_value['stderr']))
117
118
  end
118
119
  elsif result.generic_value.any?
119
120
  @stream.puts(indent(2, ::JSON.pretty_generate(result.generic_value)))
@@ -28,7 +28,7 @@ module Bolt
28
28
 
29
29
  def print_result(result)
30
30
  @stream.puts ',' if @preceding_item
31
- @stream.puts result.status_hash.to_json
31
+ @stream.puts result.to_json
32
32
  @preceding_item = true
33
33
  end
34
34
 
@@ -40,7 +40,7 @@ module Bolt
40
40
  attr_reader :modulepath
41
41
 
42
42
  def initialize(modulepath, hiera_config, resource_types, max_compiles = Etc.nprocessors,
43
- trusted_external = nil, apply_settings = {})
43
+ trusted_external = nil, apply_settings = {}, project = nil)
44
44
  # Nothing works without initialized this global state. Reinitializing
45
45
  # is safe and in practice only happens in tests
46
46
  self.class.load_puppet
@@ -52,6 +52,7 @@ module Bolt
52
52
  @apply_settings = apply_settings
53
53
  @max_compiles = max_compiles
54
54
  @resource_types = resource_types
55
+ @project = project
55
56
 
56
57
  @logger = Logging.logger[self]
57
58
  if modulepath && !modulepath.empty?
@@ -114,7 +115,7 @@ module Bolt
114
115
  compiler.evaluate_string('type PlanResult = Boltlib::PlanResult')
115
116
  end
116
117
 
117
- # Register all resource types defined in $Boltdir/.resource_types as well as
118
+ # Register all resource types defined in $Project/.resource_types as well as
118
119
  # the built in types registered with the runtime_3_init method.
119
120
  def register_resource_types(loaders)
120
121
  static_loader = loaders.static_loader
@@ -136,19 +137,34 @@ module Bolt
136
137
  # TODO: If we always call this inside a bolt_executor we can remove this here
137
138
  setup
138
139
  r = Puppet::Pal.in_tmp_environment('bolt', modulepath: @modulepath, facts: {}) do |pal|
139
- pal.with_script_compiler do |compiler|
140
- alias_types(compiler)
141
- register_resource_types(Puppet.lookup(:loaders)) if @resource_types
142
- begin
143
- Puppet.override(yaml_plan_instantiator: Bolt::PAL::YamlPlan::Loader) do
140
+ Puppet.override(bolt_project: @project,
141
+ yaml_plan_instantiator: Bolt::PAL::YamlPlan::Loader) do
142
+ pal.with_script_compiler do |compiler|
143
+ alias_types(compiler)
144
+ register_resource_types(Puppet.lookup(:loaders)) if @resource_types
145
+ begin
144
146
  yield compiler
147
+ rescue Bolt::Error => e
148
+ e
149
+ rescue Puppet::DataBinding::LookupError => e
150
+ if e.issue_code == :HIERA_UNDEFINED_VARIABLE
151
+ message = "Interpolations are not supported in lookups outside of an apply block: #{e.message}"
152
+ PALError.new(message)
153
+ else
154
+ PALError.from_preformatted_error(e)
155
+ end
156
+ rescue Puppet::PreformattedError => e
157
+ if e.issue_code == :UNKNOWN_VARIABLE &&
158
+ %w[facts trusted server_facts settings].include?(e.arguments[:name])
159
+ message = "Evaluation Error: Variable '#{e.arguments[:name]}' is not available in the current scope "\
160
+ "unless explicitly defined. (file: #{e.file}, line: #{e.line}, column: #{e.pos})"
161
+ PALError.new(message)
162
+ else
163
+ PALError.from_preformatted_error(e)
164
+ end
165
+ rescue StandardError => e
166
+ PALError.from_preformatted_error(e)
145
167
  end
146
- rescue Bolt::Error => e
147
- e
148
- rescue Puppet::PreformattedError => e
149
- PALError.from_preformatted_error(e)
150
- rescue StandardError => e
151
- PALError.from_preformatted_error(e)
152
168
  end
153
169
  end
154
170
  end
@@ -215,6 +231,7 @@ module Bolt
215
231
  Puppet.initialize_settings(cli)
216
232
  Puppet::GettextConfig.create_default_text_domain
217
233
  Puppet[:trusted_external_command] = @trusted_external
234
+ Puppet.settings[:hiera_config] = @hiera_config
218
235
  self.class.configure_logging
219
236
  yield
220
237
  end
@@ -312,7 +329,8 @@ module Bolt
312
329
  raise Bolt::Error.unknown_plan(plan_name)
313
330
  end
314
331
 
315
- mod = plan_sig.instance_variable_get(:@plan_func).loader.parent.path
332
+ # path may be a Pathname object, so make sure to stringify it
333
+ mod = plan_sig.instance_variable_get(:@plan_func).loader.parent.path.to_s
316
334
 
317
335
  # If it's a Puppet language plan, use strings to extract data. The only
318
336
  # way to tell is to check which filename exists in the module.
@@ -99,6 +99,7 @@ module Bolt
99
99
  # logic.
100
100
  class EvaluableString
101
101
  attr_reader :value
102
+
102
103
  def initialize(value)
103
104
  @value = value
104
105
  end
@@ -115,17 +115,13 @@ module Bolt
115
115
  end
116
116
 
117
117
  def boltdir
118
- @config.boltdir.path
118
+ @config.project.path
119
119
  end
120
120
  end
121
121
 
122
- def self.setup(config, pal, pdb_client, analytics)
122
+ def self.setup(config, pal, analytics = Bolt::Analytics::NoopClient.new)
123
123
  plugins = new(config, pal, analytics)
124
124
 
125
- # PDB is special because it needs the PDB client. Since it has no config,
126
- # we can just add it first.
127
- plugins.add_plugin(Bolt::Plugin::Puppetdb.new(pdb_client))
128
-
129
125
  # Initialize any plugins referenced in plugin config. This will also indirectly
130
126
  # initialize any plugins they depend on.
131
127
  if plugins.reference?(config.plugins)
@@ -142,7 +138,7 @@ module Bolt
142
138
  plugins
143
139
  end
144
140
 
145
- RUBY_PLUGINS = %w[task pkcs7 prompt env_var].freeze
141
+ RUBY_PLUGINS = %w[task prompt env_var puppetdb].freeze
146
142
  BUILTIN_PLUGINS = %w[task terraform pkcs7 prompt vault aws_inventory puppetdb azure_inventory
147
143
  yaml env_var gcloud_inventory].freeze
148
144
  DEFAULT_PLUGIN_HOOKS = { 'puppet_library' => { 'plugin' => 'puppet_agent', 'stop_service' => true } }.freeze
@@ -161,6 +157,13 @@ module Bolt
161
157
  @unknown = Set.new
162
158
  @resolution_stack = []
163
159
  @unresolved_plugin_configs = config.plugins.dup
160
+ # The puppetdb plugin config comes from the puppetdb section, not from
161
+ # the plugins section
162
+ if @unresolved_plugin_configs.key?('puppetdb')
163
+ msg = "Configuration for the PuppetDB plugin must be in the 'puppetdb' config section, not 'plugins'"
164
+ raise Bolt::Error.new(msg, 'bolt/plugin-error')
165
+ end
166
+ @unresolved_plugin_configs['puppetdb'] = config.puppetdb if config.puppetdb
164
167
  @plugin_hooks = DEFAULT_PLUGIN_HOOKS.dup
165
168
  end
166
169
 
@@ -168,7 +171,6 @@ module Bolt
168
171
  @modules ||= Bolt::Module.discover(@pal.modulepath)
169
172
  end
170
173
 
171
- # Generally this is private. Puppetdb is special though
172
174
  def add_plugin(plugin)
173
175
  @plugins[plugin.name] = plugin
174
176
  end
@@ -235,6 +237,10 @@ module Bolt
235
237
  end
236
238
  end
237
239
 
240
+ def puppetdb_client
241
+ by_name('puppetdb').puppetdb_client
242
+ end
243
+
238
244
  # Evaluate all _plugin references in a data structure. Leaves are
239
245
  # evaluated and then their parents are evaluated with references replaced
240
246
  # by their values. If the result of a reference contains more references,
@@ -17,13 +17,14 @@ module Bolt
17
17
  unless opts['var']
18
18
  raise Bolt::ValidationError, "env_var plugin requires that the 'var' is specified"
19
19
  end
20
+ return if opts['optional'] || opts['default']
20
21
  unless ENV[opts['var']]
21
22
  raise Bolt::ValidationError, "env_var plugin requires that the var '#{opts['var']}' be set"
22
23
  end
23
24
  end
24
25
 
25
26
  def resolve_reference(opts)
26
- ENV[opts['var']]
27
+ ENV[opts['var']] || opts['default']
27
28
  end
28
29
  end
29
30
  end
@@ -30,6 +30,10 @@ module Bolt
30
30
  @module = mod
31
31
  @config = config
32
32
  @context = context
33
+
34
+ if @module.name == 'pkcs7'
35
+ @config = handle_deprecated_pkcs7_keys(@config)
36
+ end
33
37
  end
34
38
 
35
39
  # This method interacts with the module on disk so it's separate from initialize
@@ -155,7 +159,21 @@ module Bolt
155
159
  # handled previously. That may not always be the case so filter them
156
160
  # out now.
157
161
  meta, params = opts.partition { |key, _val| key.start_with?('_') }.map(&:to_h)
158
- params = config.merge(params)
162
+
163
+ if task.module_name == 'pkcs7'
164
+ params = handle_deprecated_pkcs7_keys(params)
165
+ end
166
+
167
+ # Reject parameters from config that are not accepted by the task and
168
+ # merge in parameter defaults
169
+ params = if task.parameters
170
+ task.parameter_defaults
171
+ .merge(config.slice(*task.parameters.keys))
172
+ .merge(params)
173
+ else
174
+ config.merge(params)
175
+ end
176
+
159
177
  validate_params(task, params)
160
178
 
161
179
  meta['_boltdir'] = @context.boltdir.to_s
@@ -163,6 +181,23 @@ module Bolt
163
181
  [params, meta]
164
182
  end
165
183
 
184
+ # Raises a deprecation warning if the pkcs7 plugin is using deprecated keys and
185
+ # modifies the keys so they are the correct format
186
+ def handle_deprecated_pkcs7_keys(params)
187
+ if (params.key?('private-key') || params.key?('public-key')) && !@deprecation_warning_issued
188
+ @deprecation_warning_issued = true
189
+
190
+ message = "pkcs7 keys 'private-key' and 'public-key' have been deprecated and will be "\
191
+ "removed in a future version of Bolt; use 'private_key' and 'public_key' instead."
192
+ Logging.logger[self].warn(message)
193
+ end
194
+
195
+ params['private_key'] = params.delete('private-key') if params.key?('private-key')
196
+ params['public_key'] = params.delete('public-key') if params.key?('public-key')
197
+
198
+ params
199
+ end
200
+
166
201
  def extract_task_parameter_schema
167
202
  # Get the intersection of expected types (using Set)
168
203
  type_set = @hook_map.each_with_object({}) do |(_hook, task), acc|
@@ -220,13 +255,11 @@ module Bolt
220
255
  end
221
256
 
222
257
  def validate_resolve_reference(opts)
223
- # Merge config with params
224
- merged = @config.merge(opts)
225
- params = merged.reject { |k, _v| k.start_with?('_') }
258
+ task = @hook_map[:resolve_reference]['task']
259
+ params, _metaparams = process_params(task, opts)
226
260
 
227
- sig = @hook_map[:resolve_reference]['task']
228
- if sig
229
- validate_params(sig, params)
261
+ if task
262
+ validate_params(task, params)
230
263
  end
231
264
 
232
265
  if @hook_map.include?(:validate_resolve_reference)