bolt 2.22.0 → 2.23.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 +4 -4
- data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +12 -6
- data/bolt-modules/out/lib/puppet/functions/out/message.rb +1 -1
- data/lib/bolt/analytics.rb +1 -1
- data/lib/bolt/bolt_option_parser.rb +13 -14
- data/lib/bolt/cli.rb +37 -13
- data/lib/bolt/executor.rb +5 -5
- data/lib/bolt/outputter.rb +56 -0
- data/lib/bolt/outputter/human.rb +0 -9
- data/lib/bolt/outputter/json.rb +0 -4
- data/lib/bolt/pal.rb +3 -7
- data/lib/bolt/pal/yaml_plan/evaluator.rb +1 -1
- data/lib/bolt/plugin/prompt.rb +3 -3
- data/lib/bolt/project.rb +4 -2
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/pe/pal.rb +1 -1
- data/lib/bolt_spec/plans/action_stubs.rb +1 -1
- data/libexec/apply_catalog.rb +2 -2
- data/libexec/bolt_catalog +1 -1
- data/libexec/custom_facts.rb +1 -1
- data/libexec/query_resources.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f58ca99a18fca1c109d531c61b55bcee45d73c14e55a074575ffaaf1d9f40aac
|
4
|
+
data.tar.gz: ea55e4c9b9ba4ccd8afed70a6c62c603a119a46f406b573f429bd2cd89983672
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc8845ebe2a171ce79b704c474594a9679e7078feaca324eb7f26b88e9e903de43361a4dbaa357de3cf47be4ae72b4db4690a76e0910c9595f52aab384768fbc
|
7
|
+
data.tar.gz: 60b30a31debf0d031902d8df21372b2524246ee98749eeccfd588c00b3458bcb9c0ed2a1fbdeab266cce86332537bde1005aead37fece867d440d88989c2486d
|
@@ -4,30 +4,36 @@
|
|
4
4
|
Puppet::Functions.create_function(:'ctrl::do_until') do
|
5
5
|
# @param options A hash of additional options.
|
6
6
|
# @option options [Numeric] limit The number of times to repeat the block.
|
7
|
+
# @option options [Numeric] interval The number of seconds to wait before repeating the block.
|
7
8
|
# @example Run a task until it succeeds
|
8
9
|
# ctrl::do_until() || {
|
9
|
-
# run_task('test', $target, _catch_errors => true).ok()
|
10
|
+
# run_task('test', $target, '_catch_errors' => true).ok()
|
10
11
|
# }
|
11
|
-
#
|
12
12
|
# @example Run a task until it succeeds or fails 10 times
|
13
13
|
# ctrl::do_until('limit' => 10) || {
|
14
|
-
# run_task('test', $target, _catch_errors => true).ok()
|
14
|
+
# run_task('test', $target, '_catch_errors' => true).ok()
|
15
|
+
# }
|
16
|
+
# @example Run a task and wait 10 seconds before running it again
|
17
|
+
# ctrl::do_until('interval' => 10) || {
|
18
|
+
# run_task('test', $target, '_catch_errors' => true).ok()
|
15
19
|
# }
|
16
|
-
#
|
17
20
|
dispatch :do_until do
|
18
21
|
optional_param 'Hash[String[1], Any]', :options
|
19
22
|
block_param
|
20
23
|
end
|
21
24
|
|
22
|
-
def do_until(options = {
|
25
|
+
def do_until(options = {})
|
23
26
|
# Send Analytics Report
|
24
27
|
Puppet.lookup(:bolt_executor) {}&.report_function_call(self.class.name)
|
25
28
|
|
26
|
-
limit = options['limit']
|
29
|
+
limit = options['limit'] || 0
|
30
|
+
interval = options['interval']
|
31
|
+
|
27
32
|
i = 0
|
28
33
|
until (x = yield)
|
29
34
|
i += 1
|
30
35
|
break if limit != 0 && i >= limit
|
36
|
+
Kernel.sleep(interval) if interval
|
31
37
|
end
|
32
38
|
x
|
33
39
|
end
|
data/lib/bolt/analytics.rb
CHANGED
@@ -420,19 +420,18 @@ module Bolt
|
|
420
420
|
init
|
421
421
|
|
422
422
|
USAGE
|
423
|
-
bolt project init [
|
423
|
+
bolt project init [name] [options]
|
424
424
|
|
425
425
|
DESCRIPTION
|
426
|
-
Create a new Bolt project.
|
426
|
+
Create a new Bolt project in the current working directory.
|
427
427
|
|
428
|
-
Specify a
|
429
|
-
curent working directory.
|
428
|
+
Specify a name for the Bolt project. Defaults to the basename of the current working directory.
|
430
429
|
|
431
430
|
EXAMPLES
|
432
|
-
Create a new Bolt project
|
431
|
+
Create a new Bolt project using the directory as the project name.
|
433
432
|
bolt project init
|
434
|
-
Create a new Bolt project
|
435
|
-
bolt project init
|
433
|
+
Create a new Bolt project with a specified name.
|
434
|
+
bolt project init myproject
|
436
435
|
Create a new Bolt project with existing modules.
|
437
436
|
bolt project init --modules puppetlabs-apt,puppetlabs-ntp
|
438
437
|
HELP
|
@@ -694,9 +693,9 @@ module Bolt
|
|
694
693
|
@options[:password] = password
|
695
694
|
end
|
696
695
|
define('--password-prompt', 'Prompt for user to input password') do |_password|
|
697
|
-
|
698
|
-
@options[:password] =
|
699
|
-
|
696
|
+
$stderr.print "Please enter your password: "
|
697
|
+
@options[:password] = $stdin.noecho(&:gets).chomp
|
698
|
+
$stderr.puts
|
700
699
|
end
|
701
700
|
define('--private-key KEY', 'Path to private ssh key to authenticate with') do |key|
|
702
701
|
@options[:'private-key'] = File.expand_path(key)
|
@@ -720,9 +719,9 @@ module Bolt
|
|
720
719
|
@options[:'sudo-password'] = password
|
721
720
|
end
|
722
721
|
define('--sudo-password-prompt', 'Prompt for user to input escalation password') do |_password|
|
723
|
-
|
724
|
-
@options[:'sudo-password'] =
|
725
|
-
|
722
|
+
$stderr.print "Please enter your privilege escalation password: "
|
723
|
+
@options[:'sudo-password'] = $stdin.noecho(&:gets).chomp
|
724
|
+
$stderr.puts
|
726
725
|
end
|
727
726
|
define('--sudo-executable EXEC', "Specify an executable for running as another user.",
|
728
727
|
"This option is experimental.") do |exec|
|
@@ -905,7 +904,7 @@ module Bolt
|
|
905
904
|
file = value.sub(/^@/, '')
|
906
905
|
read_arg_file(file)
|
907
906
|
elsif value == '-'
|
908
|
-
|
907
|
+
$stdin.read
|
909
908
|
else
|
910
909
|
value
|
911
910
|
end
|
data/lib/bolt/cli.rb
CHANGED
@@ -526,7 +526,7 @@ module Bolt
|
|
526
526
|
tasks = pal.list_tasks
|
527
527
|
tasks.select! { |task| task.first.include?(options[:filter]) } if options[:filter]
|
528
528
|
tasks.select! { |task| config.project.tasks.include?(task.first) } unless config.project.tasks.nil?
|
529
|
-
outputter.print_tasks(tasks, pal.
|
529
|
+
outputter.print_tasks(tasks, pal.user_modulepath)
|
530
530
|
end
|
531
531
|
|
532
532
|
def show_plan(plan_name)
|
@@ -537,7 +537,7 @@ module Bolt
|
|
537
537
|
plans = pal.list_plans
|
538
538
|
plans.select! { |plan| plan.first.include?(options[:filter]) } if options[:filter]
|
539
539
|
plans.select! { |plan| config.project.plans.include?(plan.first) } unless config.project.plans.nil?
|
540
|
-
outputter.print_plans(plans, pal.
|
540
|
+
outputter.print_plans(plans, pal.user_modulepath)
|
541
541
|
end
|
542
542
|
|
543
543
|
def list_targets
|
@@ -770,8 +770,26 @@ module Bolt
|
|
770
770
|
# Initializes a specified directory as a Bolt project and installs any modules
|
771
771
|
# specified by the user, along with their dependencies
|
772
772
|
def initialize_project
|
773
|
-
|
774
|
-
|
773
|
+
# Dir.pwd will return backslashes on Windows, but Pathname always uses
|
774
|
+
# forward slashes to concatenate paths. This results in paths like
|
775
|
+
# C:\User\Administrator/modules, which fail module install. This ensure
|
776
|
+
# forward slashes in the cwd path.
|
777
|
+
dir = File.expand_path(Dir.pwd)
|
778
|
+
name = options[:object] || File.basename(dir)
|
779
|
+
if name !~ Bolt::Module::MODULE_NAME_REGEX
|
780
|
+
if options[:object]
|
781
|
+
raise Bolt::ValidationError, "The provided project name '#{name}' is invalid; "\
|
782
|
+
"project name must begin with a lowercase letter and can include lowercase "\
|
783
|
+
"letters, numbers, and underscores."
|
784
|
+
else
|
785
|
+
raise Bolt::ValidationError, "The current directory name '#{name}' is an invalid "\
|
786
|
+
"project name. Please specify a name using 'bolt project init <name>'."
|
787
|
+
end
|
788
|
+
end
|
789
|
+
|
790
|
+
project = Pathname.new(dir)
|
791
|
+
old_config = project + 'bolt.yaml'
|
792
|
+
config = project + 'bolt-project.yaml'
|
775
793
|
puppetfile = project + 'Puppetfile'
|
776
794
|
modulepath = [project + 'modules']
|
777
795
|
|
@@ -792,18 +810,24 @@ module Bolt
|
|
792
810
|
|
793
811
|
# Warn the user if the project directory already exists. We don't error here since users
|
794
812
|
# might not have installed any modules yet.
|
813
|
+
# If both bolt.yaml and bolt-project.yaml exist, this will just warn
|
814
|
+
# about bolt-project.yaml and subsequent Bolt actions will warn about
|
815
|
+
# both files existing
|
795
816
|
if config.exist?
|
796
|
-
@logger.warn "Found existing project directory at #{project}"
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
817
|
+
@logger.warn "Found existing project directory at #{project}. Skipping file creation."
|
818
|
+
# This won't get called if bolt-project.yaml exists
|
819
|
+
elsif old_config.exist?
|
820
|
+
@logger.warn "Found existing #{old_config.basename} at #{project}. "\
|
821
|
+
"#{old_config.basename} is deprecated, please rename to #{config.basename}."
|
802
822
|
# Bless the project directory as a...wait for it...project
|
803
|
-
if FileUtils.touch(config)
|
804
|
-
outputter.print_message "Successfully created Bolt project at #{project}"
|
805
823
|
else
|
806
|
-
|
824
|
+
begin
|
825
|
+
content = { 'name' => name }
|
826
|
+
File.write(config.to_path, content.to_yaml)
|
827
|
+
outputter.print_message "Successfully created Bolt project at #{project}"
|
828
|
+
rescue StandardError => e
|
829
|
+
raise Bolt::FileError.new("Could not create bolt-project.yaml at #{project}: #{e.message}", nil)
|
830
|
+
end
|
807
831
|
end
|
808
832
|
|
809
833
|
# Write the generated Puppetfile to the fancy new project
|
data/lib/bolt/executor.rb
CHANGED
@@ -381,19 +381,19 @@ module Bolt
|
|
381
381
|
end
|
382
382
|
|
383
383
|
def prompt(prompt, options)
|
384
|
-
unless
|
384
|
+
unless $stdin.tty?
|
385
385
|
raise Bolt::Error.new('STDIN is not a tty, unable to prompt', 'bolt/no-tty-error')
|
386
386
|
end
|
387
387
|
|
388
|
-
|
388
|
+
$stderr.print("#{prompt}: ")
|
389
389
|
|
390
390
|
value = if options[:sensitive]
|
391
|
-
|
391
|
+
$stdin.noecho(&:gets).to_s.chomp
|
392
392
|
else
|
393
|
-
|
393
|
+
$stdin.gets.to_s.chomp
|
394
394
|
end
|
395
395
|
|
396
|
-
|
396
|
+
$stderr.puts if options[:sensitive]
|
397
397
|
|
398
398
|
value
|
399
399
|
end
|
data/lib/bolt/outputter.rb
CHANGED
@@ -21,6 +21,62 @@ module Bolt
|
|
21
21
|
@trace = trace
|
22
22
|
@stream = stream
|
23
23
|
end
|
24
|
+
|
25
|
+
def indent(indent, string)
|
26
|
+
indent = ' ' * indent
|
27
|
+
string.gsub(/^/, indent.to_s)
|
28
|
+
end
|
29
|
+
|
30
|
+
def print_message_event(event)
|
31
|
+
print_message(stringify(event[:message]))
|
32
|
+
end
|
33
|
+
|
34
|
+
def print_message
|
35
|
+
raise NotImplementedError, "print_message() must be implemented by the outputter class"
|
36
|
+
end
|
37
|
+
|
38
|
+
def stringify(message)
|
39
|
+
formatted = format_message(message)
|
40
|
+
if formatted.is_a?(Hash) || formatted.is_a?(Array)
|
41
|
+
::JSON.pretty_generate(formatted)
|
42
|
+
else
|
43
|
+
formatted
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_message(message)
|
48
|
+
case message
|
49
|
+
when Array
|
50
|
+
message.map { |item| format_message(item) }
|
51
|
+
when Bolt::ApplyResult
|
52
|
+
format_apply_result(message)
|
53
|
+
when Bolt::Result, Bolt::ResultSet
|
54
|
+
# This is equivalent to to_s, but formattable
|
55
|
+
message.to_data
|
56
|
+
when Bolt::RunFailure
|
57
|
+
formatted_resultset = message.result_set.to_data
|
58
|
+
message.to_h.merge('result_set' => formatted_resultset)
|
59
|
+
when Hash
|
60
|
+
message.each_with_object({}) do |(k, v), h|
|
61
|
+
h[format_message(k)] = format_message(v)
|
62
|
+
end
|
63
|
+
when Integer, Float, NilClass
|
64
|
+
message
|
65
|
+
else
|
66
|
+
message.to_s
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def format_apply_result(result)
|
71
|
+
logs = result.resource_logs&.map do |log|
|
72
|
+
# Omit low-level info/debug messages
|
73
|
+
next if %w[info debug].include?(log['level'])
|
74
|
+
indent(2, format_log(log))
|
75
|
+
end
|
76
|
+
hash = result.to_data
|
77
|
+
hash['logs'] = logs unless logs.empty?
|
78
|
+
hash
|
79
|
+
end
|
24
80
|
end
|
25
81
|
end
|
26
82
|
|
data/lib/bolt/outputter/human.rb
CHANGED
@@ -27,11 +27,6 @@ module Bolt
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def indent(indent, string)
|
31
|
-
indent = ' ' * indent
|
32
|
-
string.gsub(/^/, indent.to_s)
|
33
|
-
end
|
34
|
-
|
35
30
|
def remove_trail(string)
|
36
31
|
string.sub(/\s\z/, '')
|
37
32
|
end
|
@@ -372,10 +367,6 @@ module Bolt
|
|
372
367
|
end
|
373
368
|
end
|
374
369
|
|
375
|
-
def print_message_event(event)
|
376
|
-
print_message(event[:message])
|
377
|
-
end
|
378
|
-
|
379
370
|
def fatal_error(err)
|
380
371
|
@stream.puts(colorize(:red, err.message))
|
381
372
|
if err.is_a? Bolt::RunFailure
|
data/lib/bolt/outputter/json.rb
CHANGED
data/lib/bolt/pal.rb
CHANGED
@@ -48,7 +48,7 @@ module Bolt
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
attr_reader :modulepath
|
51
|
+
attr_reader :modulepath, :user_modulepath
|
52
52
|
|
53
53
|
def initialize(modulepath, hiera_config, resource_types, max_compiles = Etc.nprocessors,
|
54
54
|
trusted_external = nil, apply_settings = {}, project = nil)
|
@@ -56,7 +56,7 @@ module Bolt
|
|
56
56
|
# is safe and in practice only happens in tests
|
57
57
|
self.class.load_puppet
|
58
58
|
|
59
|
-
@
|
59
|
+
@user_modulepath = modulepath
|
60
60
|
@modulepath = [BOLTLIB_PATH, *modulepath, MODULES_PATH]
|
61
61
|
@hiera_config = hiera_config
|
62
62
|
@trusted_external = trusted_external
|
@@ -208,7 +208,7 @@ module Bolt
|
|
208
208
|
# Skip syncing built-in plugins, since we vendor some Puppet 6
|
209
209
|
# versions of "core" types, which are already present on the agent,
|
210
210
|
# but may cause issues on Puppet 5 agents.
|
211
|
-
@
|
211
|
+
@user_modulepath,
|
212
212
|
@project,
|
213
213
|
pdb_client,
|
214
214
|
@hiera_config,
|
@@ -278,10 +278,6 @@ module Bolt
|
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
281
|
-
def list_modulepath
|
282
|
-
@modulepath - [BOLTLIB_PATH, MODULES_PATH]
|
283
|
-
end
|
284
|
-
|
285
281
|
def parse_params(type, object_name, params)
|
286
282
|
in_bolt_compiler do |compiler|
|
287
283
|
case type
|
data/lib/bolt/plugin/prompt.rb
CHANGED
@@ -18,9 +18,9 @@ module Bolt
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def resolve_reference(opts)
|
21
|
-
|
22
|
-
value =
|
23
|
-
|
21
|
+
$stderr.print("#{opts['message']}: ")
|
22
|
+
value = $stdin.noecho(&:gets).to_s.chomp
|
23
|
+
$stderr.puts
|
24
24
|
|
25
25
|
value
|
26
26
|
end
|
data/lib/bolt/project.rb
CHANGED
@@ -141,8 +141,10 @@ module Bolt
|
|
141
141
|
def validate
|
142
142
|
if name
|
143
143
|
if name !~ Bolt::Module::MODULE_NAME_REGEX
|
144
|
-
raise Bolt::ValidationError,
|
145
|
-
|
144
|
+
raise Bolt::ValidationError, <<~ERROR_STRING
|
145
|
+
Invalid project name '#{name}' in bolt-project.yaml; project name must begin with a lowercase letter
|
146
|
+
and can include lowercase letters, numbers, and underscores.
|
147
|
+
ERROR_STRING
|
146
148
|
elsif Dir.children(Bolt::PAL::BOLTLIB_PATH).include?(name)
|
147
149
|
raise Bolt::ValidationError, "The project '#{name}' will not be loaded. The project name conflicts "\
|
148
150
|
"with a built-in Bolt module of the same name."
|
data/lib/bolt/version.rb
CHANGED
data/lib/bolt_server/pe/pal.rb
CHANGED
@@ -58,7 +58,7 @@ module BoltServer
|
|
58
58
|
# Bolt::PAL::MODULES_PATH which would be more complex if we tried to use @modulepath since
|
59
59
|
# we need to append our modulepaths and exclude modules shiped in bolt gem code
|
60
60
|
modulepath_dirs = environment.modulepath
|
61
|
-
@
|
61
|
+
@user_modulepath = modulepath_dirs
|
62
62
|
@modulepath = [PE_BOLTLIB_PATH, Bolt::PAL::BOLTLIB_PATH, *modulepath_dirs]
|
63
63
|
end
|
64
64
|
end
|
@@ -177,7 +177,7 @@ module BoltSpec
|
|
177
177
|
if data['msg'] && data['kind'] && (data.keys - %w[msg kind details issue_code]).empty?
|
178
178
|
@data[:default] = clazz.new(data['msg'], data['kind'], data['details'], data['issue_code'])
|
179
179
|
else
|
180
|
-
|
180
|
+
$stderr.puts "In the future 'error_with()' may require msg and kind, and " \
|
181
181
|
"optionally accept only details and issue_code."
|
182
182
|
@data[:default] = data
|
183
183
|
end
|
data/libexec/apply_catalog.rb
CHANGED
@@ -9,7 +9,7 @@ require 'puppet/module_tool/tar'
|
|
9
9
|
require 'securerandom'
|
10
10
|
require 'tempfile'
|
11
11
|
|
12
|
-
args = JSON.parse(ARGV[0] ? File.read(ARGV[0]) :
|
12
|
+
args = JSON.parse(ARGV[0] ? File.read(ARGV[0]) : $stdin.read)
|
13
13
|
|
14
14
|
# Create temporary directories for all core Puppet settings so we don't clobber
|
15
15
|
# existing state or read from puppet.conf. Also create a temporary modulepath.
|
@@ -110,7 +110,7 @@ ensure
|
|
110
110
|
begin
|
111
111
|
FileUtils.remove_dir(puppet_root)
|
112
112
|
rescue Errno::ENOTEMPTY => e
|
113
|
-
|
113
|
+
$stderr.puts("Could not cleanup temporary directory: #{e}")
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
data/libexec/bolt_catalog
CHANGED
data/libexec/custom_facts.rb
CHANGED
data/libexec/query_resources.rb
CHANGED
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.
|
4
|
+
version: 2.23.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-08-
|
11
|
+
date: 2020-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|