bolt-modules/boltlib/lib/puppet/functions/run_command.rb in bolt-3.3.0 vs bolt-modules/boltlib/lib/puppet/functions/run_command.rb in bolt-3.4.0
- old
+ new
@@ -1,8 +1,9 @@
# frozen_string_literal: true
require 'bolt/error'
+require 'json'
# Runs a command on the given set of targets and returns the result from each command execution.
# This function does nothing if the list of targets is empty.
#
# > **Note:** Not available in apply block
@@ -11,11 +12,11 @@
# @param command A command to run on target.
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
# @param options A hash of additional options.
# @option options [Boolean] _catch_errors Whether to catch raised errors.
# @option options [String] _run_as User to run as using privilege escalation.
- # @option options [Hash] _env_vars Map of environment variables to set
+ # @option options [Hash[String, Any]] _env_vars Map of environment variables to set
# @return A list of results, one entry per target.
# @example Run a command on targets
# run_command('hostname', $targets, '_catch_errors' => true)
dispatch :run_command do
param 'String[1]', :command
@@ -29,11 +30,11 @@
# @param targets A pattern identifying zero or more targets. See {get_targets} for accepted patterns.
# @param description A description to be output when calling this function.
# @param options A hash of additional options.
# @option options [Boolean] _catch_errors Whether to catch raised errors.
# @option options [String] _run_as User to run as using privilege escalation.
- # @option options [Hash] _env_vars Map of environment variables to set
+ # @option options [Hash[String, Any]] _env_vars Map of environment variables to set
# @return A list of results, one entry per target.
# @example Run a command on targets
# run_command('hostname', $targets, 'Get hostname')
dispatch :run_command_with_description do
param 'String[1]', :command
@@ -53,9 +54,26 @@
.from_issue_and_stack(Bolt::PAL::Issues::PLAN_OPERATION_NOT_SUPPORTED_WHEN_COMPILING, action: 'run_command')
end
options = options.transform_keys { |k| k.sub(/^_/, '').to_sym }
options[:description] = description if description
+
+ # Ensure env_vars is a hash and that each hash value is transformed to JSON
+ # so we don't accidentally pass Ruby-style data to the target.
+ if options[:env_vars]
+ unless options[:env_vars].is_a?(Hash)
+ raise Bolt::ValidationError, "Option 'env_vars' must be a hash"
+ end
+
+ if (bad_keys = options[:env_vars].keys.reject { |k| k.is_a?(String) }).any?
+ raise Bolt::ValidationError,
+ "Keys for option 'env_vars' must be strings: #{bad_keys.map(&:inspect).join(', ')}"
+ end
+
+ options[:env_vars] = options[:env_vars].transform_values do |val|
+ [Array, Hash].include?(val.class) ? val.to_json : val
+ end
+ end
executor = Puppet.lookup(:bolt_executor)
inventory = Puppet.lookup(:bolt_inventory)
# Send Analytics Report