bolt 2.20.0 → 2.21.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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a72c179da8e6e3fd3d8f883366e88f98026de00eee08ae2410515b2103a3810d
4
- data.tar.gz: 968edc1c0c30a370ed06b1c9bd5498ccaaaa5e15f3c47307cad1e68f2af5dafb
3
+ metadata.gz: ef2991c1d3979e03b9070dc168be0e8c44c309914fd7eb02badc60e5b5d907bf
4
+ data.tar.gz: 9508d434488486b8b16d062f910f6d3bcf8d7b3e89121ccb8033dd393a7a21db
5
5
  SHA512:
6
- metadata.gz: a906282180c5df824978979d8e12da5cbe2f835ccef2ae65f2e2fc892bcfa1514a4f8f76418b866fe9cbfe8ce8f8f28b66306055b7acc67de6a7a2e13bb7edbf
7
- data.tar.gz: ee4c33740e8e29ad4b3026e5b75b3f0d29556c92e9277bc34101c5f8acfe80db599389c8544aab5946c6c444502a49ddb515da0a854b5796b0aae54fc0875ffc
6
+ metadata.gz: 351084ca010d6f3d051a588e0d216f07d32473026703378dd7003c9f71f411fa2499926d4e1c6272df55cffc8eeb360fbc6fff4c5a0930c14cba006dfbf3874c
7
+ data.tar.gz: eef7d1b6b0dfe5584bd216bb5ebe421b61b9e25a4131509cf310f33fc75f7a3afa072e919215eefadb43ac7415cdd51546e6b634daf53d8a7a568366bb31ee68
data/Puppetfile CHANGED
@@ -5,7 +5,7 @@ forge "http://forge.puppetlabs.com"
5
5
  moduledir File.join(File.dirname(__FILE__), 'modules')
6
6
 
7
7
  # Core modules used by 'apply'
8
- mod 'puppetlabs-service', '1.2.0'
8
+ mod 'puppetlabs-service', '1.3.0'
9
9
  mod 'puppetlabs-puppet_agent', '3.2.0'
10
10
  mod 'puppetlabs-facts', '1.0.0'
11
11
 
@@ -28,6 +28,7 @@ mod 'puppetlabs-python_task_helper', '0.4.3'
28
28
  mod 'puppetlabs-reboot', '3.0.0'
29
29
  mod 'puppetlabs-ruby_task_helper', '0.5.1'
30
30
  mod 'puppetlabs-ruby_plugin_helper', '0.1.0'
31
+ mod 'puppetlabs-stdlib', '6.3.0'
31
32
 
32
33
  # Plugin modules
33
34
  mod 'puppetlabs-aws_inventory', '0.5.0'
@@ -42,3 +43,4 @@ mod 'puppetlabs-yaml', '0.2.0'
42
43
  mod 'canary', local: true
43
44
  mod 'aggregate', local: true
44
45
  mod 'puppetdb_fact', local: true
46
+ mod 'secure_env_vars', local: true
@@ -11,6 +11,9 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
11
11
  # @param args A hash of arguments to the plan. Can also include additional options.
12
12
  # @option args [Boolean] _catch_errors Whether to catch raised errors.
13
13
  # @option args [String] _run_as User to run as using privilege escalation.
14
+ # This option sets the [run-as user](privilege_escalation.md) for all
15
+ # targets whenever Bolt connects to a target. This is set for all functions
16
+ # in the called plan, including `run_plan()`.
14
17
  # @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
15
18
  # @example Run a plan
16
19
  # run_plan('canary', 'command' => 'false', 'targets' => $targets, '_catch_errors' => true)
@@ -31,6 +34,9 @@ Puppet::Functions.create_function(:run_plan, Puppet::Functions::InternalFunction
31
34
  # @param args A hash of arguments to the plan. Can also include additional options.
32
35
  # @option args [Boolean] _catch_errors Whether to catch raised errors.
33
36
  # @option args [String] _run_as User to run as using privilege escalation.
37
+ # This option sets the [run-as user](privilege_escalation.md) for all
38
+ # targets whenever Bolt connects to a target. This is set for all functions
39
+ # in the called plan, including `run_plan()`.
34
40
  # @return [PlanResult] The result of running the plan. Undef if plan does not explicitly return results.
35
41
  # @example Run a plan
36
42
  # run_plan('canary', $targets, 'command' => 'false')
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pathname'
4
+
5
+ # Returns an array containing all of the filenames except for "." and ".." in the given directory.
6
+ Puppet::Functions.create_function(:'dir::children', Puppet::Functions::InternalFunction) do
7
+ # @param dirname Absolute path or Puppet module name.
8
+ # @return Array of files in the given directory.
9
+ # @example List filenames from an absolute path.
10
+ # dir::children('/home/user/subdir/')
11
+ # @example List filenames from a Puppet file path.
12
+ # dir::children('puppet_agent')
13
+ dispatch :children do
14
+ scope_param
15
+ required_param 'String', :dirname
16
+ return_type 'Array'
17
+ end
18
+
19
+ def children(scope, dirname)
20
+ # Send Analytics Report
21
+ Puppet.lookup(:bolt_executor) {}&.report_function_call(self.class.name)
22
+ modname, subpath = dirname.split(File::SEPARATOR, 2)
23
+ mod_path = scope.compiler.environment.module(modname)&.path
24
+
25
+ full_mod_path = File.join(mod_path, subpath || '') if mod_path
26
+
27
+ # Expand relative to the project directory if path is relative
28
+ project = Puppet.lookup(:bolt_project_data)
29
+ pathname = Pathname.new(dirname)
30
+ full_dir = pathname.absolute? ? dirname : File.expand_path(File.join(project.path, dirname))
31
+
32
+ # Sort for testability
33
+ Dir.children(full_mod_path || full_dir).sort
34
+ end
35
+ end
@@ -25,7 +25,7 @@ module Bolt
25
25
  when 'command'
26
26
  case action
27
27
  when 'run'
28
- { flags: ACTION_OPTS,
28
+ { flags: ACTION_OPTS + %w[env-var],
29
29
  banner: COMMAND_RUN_HELP }
30
30
  else
31
31
  { flags: OPTIONS[:global],
@@ -106,7 +106,7 @@ module Bolt
106
106
  when 'script'
107
107
  case action
108
108
  when 'run'
109
- { flags: ACTION_OPTS + %w[tmpdir],
109
+ { flags: ACTION_OPTS + %w[tmpdir env-var],
110
110
  banner: SCRIPT_RUN_HELP }
111
111
  else
112
112
  { flags: OPTIONS[:global],
@@ -761,6 +761,15 @@ module Bolt
761
761
  @options[:'save-rerun'] = save
762
762
  end
763
763
 
764
+ separator "\nREMOTE ENVIRONMENT OPTIONS"
765
+ define('--env-var ENVIRONMENT_VARIABLES', 'Environment variables to set on the target') do |envvar|
766
+ unless envvar.include?('=')
767
+ raise Bolt::CLIError, "Environment variables must be specified using 'myenvvar=key' format"
768
+ end
769
+ @options[:env_vars] ||= {}
770
+ @options[:env_vars].store(*envvar.split('=', 2))
771
+ end
772
+
764
773
  separator "\nTRANSPORT OPTIONS"
765
774
  define('--transport TRANSPORT', TRANSPORTS.keys.map(&:to_s),
766
775
  "Specify a default transport: #{TRANSPORTS.keys.join(', ')}") do |t|
@@ -258,6 +258,13 @@ module Bolt
258
258
  "Option '--noop' may only be specified when running a task or applying manifest code"
259
259
  end
260
260
 
261
+ if options[:env_vars]
262
+ unless %w[command script].include?(options[:subcommand]) && options[:action] == 'run'
263
+ raise Bolt::CLIError,
264
+ "Option '--env-var' may only be specified when running a command or script"
265
+ end
266
+ end
267
+
261
268
  if options[:subcommand] == 'apply' && (options[:object] && options[:code])
262
269
  raise Bolt::CLIError, "--execute is unsupported when specifying a manifest file"
263
270
  end
@@ -450,6 +457,7 @@ module Bolt
450
457
  elapsed_time = Benchmark.realtime do
451
458
  executor_opts = {}
452
459
  executor_opts[:description] = options[:description] if options.key?(:description)
460
+ executor_opts[:env_vars] = options[:env_vars] if options.key?(:env_vars)
453
461
  executor.subscribe(outputter)
454
462
  executor.subscribe(log_outputter)
455
463
  results =
@@ -322,7 +322,13 @@ module Bolt
322
322
 
323
323
  def download_file(targets, source, destination, options = {})
324
324
  description = options.fetch(:description, "file download from #{source} to #{destination}")
325
- FileUtils.mkdir_p(destination)
325
+
326
+ begin
327
+ FileUtils.mkdir_p(destination)
328
+ rescue Errno::EEXIST => e
329
+ message = "#{e.message}; unable to create destination directory #{destination}"
330
+ raise Bolt::Error.new(message, 'bolt/file-exist-error')
331
+ end
326
332
 
327
333
  log_action(description, targets) do
328
334
  options[:run_as] = run_as if run_as && !options.key?(:run_as)
@@ -108,6 +108,10 @@ module Bolt
108
108
  apply_manifest(scope, targets, manifest)
109
109
  end
110
110
 
111
+ def message_step(scope, step)
112
+ scope.call_function('out::message', step['message'])
113
+ end
114
+
111
115
  def generate_manifest(resources)
112
116
  # inspect returns the Ruby representation of the resource hashes,
113
117
  # which happens to be the same as the Puppet representation
@@ -12,7 +12,19 @@ module Bolt
12
12
  Set['name', 'description', 'target', 'targets']
13
13
  end
14
14
 
15
- STEP_KEYS = %w[command script task plan source destination eval resources upload download].freeze
15
+ STEP_KEYS = %w[
16
+ command
17
+ destination
18
+ download
19
+ eval
20
+ message
21
+ plan
22
+ resources
23
+ script
24
+ source
25
+ task
26
+ upload
27
+ ].freeze
16
28
 
17
29
  def self.create(step_body, step_number)
18
30
  type_keys = (STEP_KEYS & step_body.keys)
@@ -165,3 +177,4 @@ require 'bolt/pal/yaml_plan/step/script'
165
177
  require 'bolt/pal/yaml_plan/step/task'
166
178
  require 'bolt/pal/yaml_plan/step/upload'
167
179
  require 'bolt/pal/yaml_plan/step/download'
180
+ require 'bolt/pal/yaml_plan/step/message'
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Bolt
4
+ class PAL
5
+ class YamlPlan
6
+ class Step
7
+ class Message < Step
8
+ def self.allowed_keys
9
+ super + Set['message']
10
+ end
11
+
12
+ def self.required_keys
13
+ Set['message']
14
+ end
15
+
16
+ def initialize(step_body)
17
+ super
18
+ @message = step_body['message']
19
+ end
20
+
21
+ def transpile
22
+ code = String.new(" ")
23
+ code << function_call('out::message', [@message])
24
+ code << "\n"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -111,12 +111,21 @@ module Bolt
111
111
  out_rd, out_wr = IO.pipe('UTF-8')
112
112
  err_rd, err_wr = IO.pipe('UTF-8')
113
113
  th = Thread.new do
114
+ # By default, any exception raised in a thread will be reported to
115
+ # stderr as a stacktrace. Since we know these errors are going to
116
+ # propagate to the main thread via the shell, there's no chance
117
+ # they will be unhandled, so the default stack trace is unneeded.
118
+ Thread.current.report_on_exception = false
114
119
  result = @session.run(command)
115
120
  out_wr << result.stdout
116
121
  err_wr << result.stderr
117
122
  out_wr.close
118
123
  err_wr.close
119
124
  result.exitcode
125
+ ensure
126
+ # Close the streams to avoid the caller deadlocking
127
+ out_wr.close
128
+ err_wr.close
120
129
  end
121
130
 
122
131
  [inp, out_rd, err_rd, th]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bolt
4
- VERSION = '2.20.0'
4
+ VERSION = '2.21.0'
5
5
  end
@@ -0,0 +1,20 @@
1
+ plan secure_env_vars(
2
+ TargetSpec $targets,
3
+ Optional[String] $command = undef,
4
+ Optional[String] $script = undef
5
+ ) {
6
+ $env_vars = parsejson(system::env('BOLT_ENV_VARS'))
7
+ unless type($command) == Undef or type($script) == Undef {
8
+ fail_plan('Cannot specify both script and command for secure_env_vars')
9
+ }
10
+
11
+ return if $command {
12
+ run_command($command, $targets, '_env_vars' => $env_vars)
13
+ }
14
+ elsif $script {
15
+ run_script($script, $targets, '_env_vars' => $env_vars)
16
+ }
17
+ else {
18
+ fail_plan('Must specify either script or command for secure_env_vars')
19
+ }
20
+ }
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: 2.20.0
4
+ version: 2.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-27 00:00:00.000000000 Z
11
+ date: 2020-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -427,6 +427,7 @@ files:
427
427
  - bolt-modules/boltlib/types/targetspec.pp
428
428
  - bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb
429
429
  - bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb
430
+ - bolt-modules/dir/lib/puppet/functions/dir/children.rb
430
431
  - bolt-modules/file/lib/puppet/functions/file/exists.rb
431
432
  - bolt-modules/file/lib/puppet/functions/file/join.rb
432
433
  - bolt-modules/file/lib/puppet/functions/file/read.rb
@@ -482,6 +483,7 @@ files:
482
483
  - lib/bolt/pal/yaml_plan/step/command.rb
483
484
  - lib/bolt/pal/yaml_plan/step/download.rb
484
485
  - lib/bolt/pal/yaml_plan/step/eval.rb
486
+ - lib/bolt/pal/yaml_plan/step/message.rb
485
487
  - lib/bolt/pal/yaml_plan/step/plan.rb
486
488
  - lib/bolt/pal/yaml_plan/step/resources.rb
487
489
  - lib/bolt/pal/yaml_plan/step/script.rb
@@ -576,6 +578,7 @@ files:
576
578
  - modules/canary/lib/puppet/functions/canary/skip.rb
577
579
  - modules/canary/plans/init.pp
578
580
  - modules/puppetdb_fact/plans/init.pp
581
+ - modules/secure_env_vars/plans/init.pp
579
582
  homepage: https://github.com/puppetlabs/bolt
580
583
  licenses:
581
584
  - Apache-2.0