bolt 2.16.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 +4 -4
- data/Puppetfile +3 -1
- data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +20 -9
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +123 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +2 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +6 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +6 -4
- data/bolt-modules/dir/lib/puppet/functions/dir/children.rb +35 -0
- data/lib/bolt/applicator.rb +19 -14
- data/lib/bolt/apply_result.rb +1 -1
- data/lib/bolt/bolt_option_parser.rb +60 -16
- data/lib/bolt/catalog.rb +3 -2
- data/lib/bolt/cli.rb +121 -43
- data/lib/bolt/config.rb +37 -34
- data/lib/bolt/config/options.rb +340 -173
- data/lib/bolt/config/transport/options.rb +315 -160
- data/lib/bolt/config/transport/ssh.rb +24 -10
- data/lib/bolt/executor.rb +21 -0
- data/lib/bolt/inventory/group.rb +3 -2
- data/lib/bolt/inventory/inventory.rb +4 -3
- data/lib/bolt/logger.rb +24 -1
- data/lib/bolt/outputter.rb +1 -1
- data/lib/bolt/outputter/rainbow.rb +14 -3
- data/lib/bolt/pal.rb +28 -10
- data/lib/bolt/pal/yaml_plan/evaluator.rb +23 -2
- data/lib/bolt/pal/yaml_plan/step.rb +24 -2
- data/lib/bolt/pal/yaml_plan/step/download.rb +38 -0
- data/lib/bolt/pal/yaml_plan/step/message.rb +30 -0
- data/lib/bolt/pal/yaml_plan/step/upload.rb +3 -3
- data/lib/bolt/plugin/module.rb +2 -4
- data/lib/bolt/plugin/puppetdb.rb +3 -2
- data/lib/bolt/project.rb +20 -6
- data/lib/bolt/puppetdb/client.rb +2 -0
- data/lib/bolt/puppetdb/config.rb +16 -0
- data/lib/bolt/result.rb +7 -0
- data/lib/bolt/shell/bash.rb +45 -37
- data/lib/bolt/shell/powershell.rb +21 -11
- data/lib/bolt/shell/powershell/snippets.rb +15 -6
- data/lib/bolt/transport/base.rb +24 -0
- data/lib/bolt/transport/docker.rb +16 -4
- data/lib/bolt/transport/docker/connection.rb +20 -2
- data/lib/bolt/transport/local/connection.rb +14 -1
- data/lib/bolt/transport/orch.rb +20 -0
- data/lib/bolt/transport/simple.rb +6 -0
- data/lib/bolt/transport/ssh.rb +7 -1
- data/lib/bolt/transport/ssh/connection.rb +9 -1
- data/lib/bolt/transport/ssh/exec_connection.rb +23 -2
- data/lib/bolt/transport/winrm/connection.rb +118 -8
- data/lib/bolt/util.rb +26 -11
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/transport_app.rb +3 -2
- data/lib/bolt_spec/bolt_context.rb +7 -2
- data/lib/bolt_spec/plans.rb +15 -2
- data/lib/bolt_spec/plans/action_stubs.rb +2 -1
- data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
- data/lib/bolt_spec/plans/mock_executor.rb +14 -1
- data/lib/bolt_spec/run.rb +22 -0
- data/libexec/bolt_catalog +3 -2
- data/modules/secure_env_vars/plans/init.pp +20 -0
- metadata +21 -29
data/lib/bolt/catalog.rb
CHANGED
@@ -138,9 +138,10 @@ module Bolt
|
|
138
138
|
# That means the apply body either a) consists of just a
|
139
139
|
# NodeDefinition, b) consists of a BlockExpression which may
|
140
140
|
# contain NodeDefinitions, or c) doesn't contain NodeDefinitions.
|
141
|
-
definitions =
|
141
|
+
definitions = case ast
|
142
|
+
when Puppet::Pops::Model::BlockExpression
|
142
143
|
ast.statements.select { |st| st.is_a?(Puppet::Pops::Model::NodeDefinition) }
|
143
|
-
|
144
|
+
when Puppet::Pops::Model::NodeDefinition
|
144
145
|
[ast]
|
145
146
|
else
|
146
147
|
[]
|
data/lib/bolt/cli.rb
CHANGED
@@ -32,7 +32,7 @@ module Bolt
|
|
32
32
|
'script' => %w[run],
|
33
33
|
'task' => %w[show run],
|
34
34
|
'plan' => %w[show run convert],
|
35
|
-
'file' => %w[upload],
|
35
|
+
'file' => %w[download upload],
|
36
36
|
'puppetfile' => %w[install show-modules generate-types],
|
37
37
|
'secret' => %w[encrypt decrypt createkeys],
|
38
38
|
'inventory' => %w[show],
|
@@ -46,7 +46,6 @@ module Bolt
|
|
46
46
|
Bolt::Logger.initialize_logging
|
47
47
|
@logger = Logging.logger[self]
|
48
48
|
@argv = argv
|
49
|
-
@config = Bolt::Config.default
|
50
49
|
@options = {}
|
51
50
|
end
|
52
51
|
|
@@ -76,7 +75,23 @@ module Bolt
|
|
76
75
|
end
|
77
76
|
private :help?
|
78
77
|
|
78
|
+
# Wrapper method that is called by the Bolt executable. Parses the command and
|
79
|
+
# then loads the project and config. Once config is loaded, it completes the
|
80
|
+
# setup process by configuring Bolt and issuing warnings.
|
81
|
+
#
|
82
|
+
# This separation is needed since the Bolt::Outputter class that normally handles
|
83
|
+
# printing errors relies on config being loaded. All setup that happens before
|
84
|
+
# config is loaded will have errors printed directly to stdout, while all errors
|
85
|
+
# raised after config is loaded are handled by the outputter.
|
79
86
|
def parse
|
87
|
+
parse_command
|
88
|
+
load_config
|
89
|
+
finalize_setup
|
90
|
+
end
|
91
|
+
|
92
|
+
# Parses the command and validates options. All errors that are raised here
|
93
|
+
# are not handled by the outputter, as it relies on config being loaded.
|
94
|
+
def parse_command
|
80
95
|
parser = BoltOptionParser.new(options)
|
81
96
|
# This part aims to handle both `bolt <mode> --help` and `bolt help <mode>`.
|
82
97
|
remaining = handle_parser_errors { parser.permute(@argv) } unless @argv.empty?
|
@@ -109,51 +124,66 @@ module Bolt
|
|
109
124
|
end
|
110
125
|
options[:leftovers] = remaining
|
111
126
|
|
127
|
+
# Default to verbose for everything except plans
|
128
|
+
unless options.key?(:verbose)
|
129
|
+
options[:verbose] = options[:subcommand] != 'plan'
|
130
|
+
end
|
131
|
+
|
112
132
|
validate(options)
|
113
133
|
|
114
|
-
|
134
|
+
# Deprecation warnings can't be issued until after config is loaded, so
|
135
|
+
# store them for later.
|
136
|
+
@parser_deprecations = parser.deprecations
|
137
|
+
rescue Bolt::Error => e
|
138
|
+
fatal_error(e)
|
139
|
+
raise e
|
140
|
+
end
|
141
|
+
|
142
|
+
# Loads the project and configuration. All errors that are raised here are not
|
143
|
+
# handled by the outputter, as it relies on config being loaded.
|
144
|
+
def load_config
|
145
|
+
@config = if ENV['BOLT_PROJECT']
|
146
|
+
project = Bolt::Project.create_project(ENV['BOLT_PROJECT'], 'environment')
|
147
|
+
Bolt::Config.from_project(project, options)
|
148
|
+
elsif options[:configfile]
|
115
149
|
Bolt::Config.from_file(options[:configfile], options)
|
116
150
|
else
|
117
151
|
project = if options[:boltdir]
|
118
|
-
|
152
|
+
dir = Pathname.new(options[:boltdir])
|
153
|
+
if (dir + Bolt::Project::BOLTDIR_NAME).directory?
|
154
|
+
Bolt::Project.create_project(dir + Bolt::Project::BOLTDIR_NAME)
|
155
|
+
else
|
156
|
+
Bolt::Project.create_project(dir)
|
157
|
+
end
|
119
158
|
else
|
120
159
|
Bolt::Project.find_boltdir(Dir.pwd)
|
121
160
|
end
|
122
161
|
Bolt::Config.from_project(project, options)
|
123
162
|
end
|
163
|
+
rescue Bolt::Error => e
|
164
|
+
fatal_error(e)
|
165
|
+
raise e
|
166
|
+
end
|
124
167
|
|
168
|
+
# Completes the setup process by configuring Bolt and issuing warnings
|
169
|
+
def finalize_setup
|
125
170
|
Bolt::Logger.configure(config.log, config.color)
|
171
|
+
Bolt::Logger.analytics = analytics
|
126
172
|
|
127
173
|
# Logger must be configured before checking path case and project file, otherwise warnings will not display
|
128
|
-
|
129
|
-
|
174
|
+
config.check_path_case('modulepath', config.modulepath)
|
175
|
+
config.project.check_deprecated_file
|
130
176
|
|
131
177
|
# Log the file paths for loaded config files
|
132
178
|
config_loaded
|
133
179
|
|
134
180
|
# Display warnings created during parser and config initialization
|
135
|
-
parser.warnings.each { |warning| @logger.warn(warning[:msg]) }
|
136
181
|
config.warnings.each { |warning| @logger.warn(warning[:msg]) }
|
137
|
-
|
138
|
-
|
139
|
-
# After this step
|
140
|
-
# options[:target_args] will contain a string/array version of the targetting options this is passed to plans
|
141
|
-
# options[:targets] will contain a resolved set of Target objects
|
142
|
-
unless options[:subcommand] == 'puppetfile' ||
|
143
|
-
options[:subcommand] == 'secret' ||
|
144
|
-
options[:subcommand] == 'project' ||
|
145
|
-
options[:action] == 'show' ||
|
146
|
-
options[:action] == 'convert'
|
147
|
-
|
148
|
-
update_targets(options)
|
149
|
-
end
|
150
|
-
|
151
|
-
unless options.key?(:verbose)
|
152
|
-
# Default to verbose for everything except plans
|
153
|
-
options[:verbose] = options[:subcommand] != 'plan'
|
154
|
-
end
|
182
|
+
@parser_deprecations.each { |dep| Bolt::Logger.deprecation_warning(dep[:type], dep[:msg]) }
|
183
|
+
config.deprecations.each { |dep| Bolt::Logger.deprecation_warning(dep[:type], dep[:msg]) }
|
155
184
|
|
156
185
|
warn_inventory_overrides_cli(options)
|
186
|
+
|
157
187
|
options
|
158
188
|
rescue Bolt::Error => e
|
159
189
|
outputter.fatal_error(e)
|
@@ -228,6 +258,13 @@ module Bolt
|
|
228
258
|
"Option '--noop' may only be specified when running a task or applying manifest code"
|
229
259
|
end
|
230
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
|
+
|
231
268
|
if options[:subcommand] == 'apply' && (options[:object] && options[:code])
|
232
269
|
raise Bolt::CLIError, "--execute is unsupported when specifying a manifest file"
|
233
270
|
end
|
@@ -245,6 +282,10 @@ module Bolt
|
|
245
282
|
!options[:object]
|
246
283
|
raise Bolt::CLIError, "Must specify a value to #{options[:action]}"
|
247
284
|
end
|
285
|
+
|
286
|
+
if options.key?(:debug) && options.key?(:log)
|
287
|
+
raise Bolt::CLIError, "Only one of '--debug' or '--log-level' may be specified"
|
288
|
+
end
|
248
289
|
end
|
249
290
|
|
250
291
|
def handle_parser_errors
|
@@ -272,12 +313,12 @@ module Bolt
|
|
272
313
|
def warn_inventory_overrides_cli(opts)
|
273
314
|
inventory_source = if ENV[Bolt::Inventory::ENVIRONMENT_VAR]
|
274
315
|
Bolt::Inventory::ENVIRONMENT_VAR
|
275
|
-
elsif
|
276
|
-
|
316
|
+
elsif config.inventoryfile && Bolt::Util.file_stat(config.inventoryfile)
|
317
|
+
config.inventoryfile
|
277
318
|
else
|
278
319
|
begin
|
279
|
-
Bolt::Util.file_stat(
|
280
|
-
|
320
|
+
Bolt::Util.file_stat(config.default_inventoryfile)
|
321
|
+
config.default_inventoryfile
|
281
322
|
rescue Errno::ENOENT
|
282
323
|
nil
|
283
324
|
end
|
@@ -306,6 +347,17 @@ module Bolt
|
|
306
347
|
exit!
|
307
348
|
end
|
308
349
|
|
350
|
+
# Initialize inventory and targets. Errors here are better to catch early.
|
351
|
+
# options[:target_args] will contain a string/array version of the targetting options this is passed to plans
|
352
|
+
# options[:targets] will contain a resolved set of Target objects
|
353
|
+
unless options[:subcommand] == 'puppetfile' ||
|
354
|
+
options[:subcommand] == 'secret' ||
|
355
|
+
options[:subcommand] == 'project' ||
|
356
|
+
options[:action] == 'show' ||
|
357
|
+
options[:action] == 'convert'
|
358
|
+
update_targets(options)
|
359
|
+
end
|
360
|
+
|
309
361
|
if options[:action] == 'convert'
|
310
362
|
convert_plan(options[:object])
|
311
363
|
return 0
|
@@ -334,30 +386,32 @@ module Bolt
|
|
334
386
|
|
335
387
|
analytics.screen_view(screen, screen_view_fields)
|
336
388
|
|
337
|
-
|
338
|
-
|
389
|
+
case options[:action]
|
390
|
+
when 'show'
|
391
|
+
case options[:subcommand]
|
392
|
+
when 'task'
|
339
393
|
if options[:object]
|
340
394
|
show_task(options[:object])
|
341
395
|
else
|
342
396
|
list_tasks
|
343
397
|
end
|
344
|
-
|
398
|
+
when 'plan'
|
345
399
|
if options[:object]
|
346
400
|
show_plan(options[:object])
|
347
401
|
else
|
348
402
|
list_plans
|
349
403
|
end
|
350
|
-
|
404
|
+
when 'inventory'
|
351
405
|
if options[:detail]
|
352
406
|
show_targets
|
353
407
|
else
|
354
408
|
list_targets
|
355
409
|
end
|
356
|
-
|
410
|
+
when 'group'
|
357
411
|
list_groups
|
358
412
|
end
|
359
413
|
return 0
|
360
|
-
|
414
|
+
when 'show-modules'
|
361
415
|
list_modules
|
362
416
|
return 0
|
363
417
|
end
|
@@ -370,18 +424,20 @@ module Bolt
|
|
370
424
|
|
371
425
|
case options[:subcommand]
|
372
426
|
when 'project'
|
373
|
-
|
427
|
+
case options[:action]
|
428
|
+
when 'init'
|
374
429
|
code = initialize_project
|
375
|
-
|
430
|
+
when 'migrate'
|
376
431
|
code = migrate_project
|
377
432
|
end
|
378
433
|
when 'plan'
|
379
434
|
code = run_plan(options[:object], options[:task_options], options[:target_args], options)
|
380
435
|
when 'puppetfile'
|
381
|
-
|
436
|
+
case options[:action]
|
437
|
+
when 'generate-types'
|
382
438
|
code = generate_types
|
383
|
-
|
384
|
-
code = install_puppetfile(
|
439
|
+
when 'install'
|
440
|
+
code = install_puppetfile(config.puppetfile_config, config.puppetfile, config.modulepath)
|
385
441
|
end
|
386
442
|
when 'secret'
|
387
443
|
code = Bolt::Secret.execute(plugins, outputter, options)
|
@@ -401,6 +457,7 @@ module Bolt
|
|
401
457
|
elapsed_time = Benchmark.realtime do
|
402
458
|
executor_opts = {}
|
403
459
|
executor_opts[:description] = options[:description] if options.key?(:description)
|
460
|
+
executor_opts[:env_vars] = options[:env_vars] if options.key?(:env_vars)
|
404
461
|
executor.subscribe(outputter)
|
405
462
|
executor.subscribe(log_outputter)
|
406
463
|
results =
|
@@ -422,11 +479,22 @@ module Bolt
|
|
422
479
|
src = options[:object]
|
423
480
|
dest = options[:leftovers].first
|
424
481
|
|
482
|
+
if src.nil?
|
483
|
+
raise Bolt::CLIError, "A source path must be specified"
|
484
|
+
end
|
485
|
+
|
425
486
|
if dest.nil?
|
426
487
|
raise Bolt::CLIError, "A destination path must be specified"
|
427
488
|
end
|
428
|
-
|
429
|
-
|
489
|
+
|
490
|
+
case options[:action]
|
491
|
+
when 'download'
|
492
|
+
dest = File.expand_path(dest, Dir.pwd)
|
493
|
+
executor.download_file(targets, src, dest, executor_opts)
|
494
|
+
when 'upload'
|
495
|
+
validate_file('source file', src, true)
|
496
|
+
executor.upload_file(targets, src, dest, executor_opts)
|
497
|
+
end
|
430
498
|
end
|
431
499
|
end
|
432
500
|
|
@@ -793,7 +861,7 @@ module Bolt
|
|
793
861
|
end
|
794
862
|
|
795
863
|
def rerun
|
796
|
-
@rerun ||= Bolt::Rerun.new(
|
864
|
+
@rerun ||= Bolt::Rerun.new(config.rerunfile, config.save_rerun)
|
797
865
|
end
|
798
866
|
|
799
867
|
def outputter
|
@@ -856,5 +924,15 @@ module Bolt
|
|
856
924
|
def incomplete_install?
|
857
925
|
(Dir.children(Bolt::PAL::MODULES_PATH) - %w[aggregate canary puppetdb_fact]).empty?
|
858
926
|
end
|
927
|
+
|
928
|
+
# Mimicks the output from Outputter::Human#fatal_error. This should be used to print
|
929
|
+
# errors prior to config being loaded, as the outputter relies on config being loaded.
|
930
|
+
def fatal_error(error)
|
931
|
+
if $stdout.isatty
|
932
|
+
$stdout.puts("\033[31m#{error.message}\033[0m")
|
933
|
+
else
|
934
|
+
$stdout.puts(error.message)
|
935
|
+
end
|
936
|
+
end
|
859
937
|
end
|
860
938
|
end
|
data/lib/bolt/config.rb
CHANGED
@@ -6,13 +6,6 @@ require 'pathname'
|
|
6
6
|
require 'bolt/project'
|
7
7
|
require 'bolt/logger'
|
8
8
|
require 'bolt/util'
|
9
|
-
# Transport config objects
|
10
|
-
require 'bolt/config/transport/ssh'
|
11
|
-
require 'bolt/config/transport/winrm'
|
12
|
-
require 'bolt/config/transport/orch'
|
13
|
-
require 'bolt/config/transport/local'
|
14
|
-
require 'bolt/config/transport/docker'
|
15
|
-
require 'bolt/config/transport/remote'
|
16
9
|
require 'bolt/config/options'
|
17
10
|
|
18
11
|
module Bolt
|
@@ -26,27 +19,16 @@ module Bolt
|
|
26
19
|
class Config
|
27
20
|
include Bolt::Config::Options
|
28
21
|
|
29
|
-
attr_reader :config_files, :warnings, :data, :transports, :project, :modified_concurrency
|
22
|
+
attr_reader :config_files, :warnings, :data, :transports, :project, :modified_concurrency, :deprecations
|
30
23
|
|
31
24
|
BOLT_CONFIG_NAME = 'bolt.yaml'
|
32
25
|
BOLT_DEFAULTS_NAME = 'bolt-defaults.yaml'
|
33
26
|
|
34
|
-
# Transport config classes. Used to load default transport config which
|
35
|
-
# gets passed along to the inventory.
|
36
|
-
TRANSPORT_CONFIG = {
|
37
|
-
'ssh' => Bolt::Config::Transport::SSH,
|
38
|
-
'winrm' => Bolt::Config::Transport::WinRM,
|
39
|
-
'pcp' => Bolt::Config::Transport::Orch,
|
40
|
-
'local' => Bolt::Config::Transport::Local,
|
41
|
-
'docker' => Bolt::Config::Transport::Docker,
|
42
|
-
'remote' => Bolt::Config::Transport::Remote
|
43
|
-
}.freeze
|
44
|
-
|
45
27
|
# The default concurrency value that is used when the ulimit is not low (i.e. < 700)
|
46
28
|
DEFAULT_DEFAULT_CONCURRENCY = 100
|
47
29
|
|
48
30
|
def self.default
|
49
|
-
new(Bolt::Project.
|
31
|
+
new(Bolt::Project.default_project, {})
|
50
32
|
end
|
51
33
|
|
52
34
|
def self.from_project(project, overrides = {})
|
@@ -59,7 +41,8 @@ module Bolt
|
|
59
41
|
data = load_defaults(project).push(
|
60
42
|
filepath: project.config_file,
|
61
43
|
data: conf,
|
62
|
-
warnings: []
|
44
|
+
warnings: [],
|
45
|
+
deprecations: []
|
63
46
|
)
|
64
47
|
|
65
48
|
new(project, data, overrides)
|
@@ -77,7 +60,8 @@ module Bolt
|
|
77
60
|
data = load_defaults(project).push(
|
78
61
|
filepath: project.config_file,
|
79
62
|
data: conf,
|
80
|
-
warnings: []
|
63
|
+
warnings: [],
|
64
|
+
deprecations: []
|
81
65
|
)
|
82
66
|
|
83
67
|
new(project, data, overrides)
|
@@ -139,13 +123,26 @@ module Bolt
|
|
139
123
|
)
|
140
124
|
end
|
141
125
|
|
142
|
-
# Move data under
|
143
|
-
# config from other sources.
|
126
|
+
# Move data under inventory-config to top-level so it can be easily merged with
|
127
|
+
# config from other sources. Error early if inventory-config is not a hash or
|
128
|
+
# has a plugin reference.
|
144
129
|
if data.key?('inventory-config')
|
130
|
+
unless data['inventory-config'].is_a?(Hash)
|
131
|
+
raise Bolt::ValidationError,
|
132
|
+
"Option 'inventory-config' must be of type Hash, received #{data['inventory-config']} "\
|
133
|
+
"#{data['inventory-config']} (file: #{filepath})"
|
134
|
+
end
|
135
|
+
|
136
|
+
if data['inventory-config'].key?('_plugin')
|
137
|
+
raise Bolt::ValidationError,
|
138
|
+
"Found unsupported key '_plugin' for option 'inventory-config'; supported keys are "\
|
139
|
+
"'#{INVENTORY_OPTIONS.keys.join("', '")}' (file: #{filepath})"
|
140
|
+
end
|
141
|
+
|
145
142
|
data = data.merge(data.delete('inventory-config'))
|
146
143
|
end
|
147
144
|
|
148
|
-
{ filepath: filepath, data: data, warnings: warnings }
|
145
|
+
{ filepath: filepath, data: data, warnings: warnings, deprecations: [] }
|
149
146
|
end
|
150
147
|
|
151
148
|
# Loads a 'bolt.yaml' file, the legacy configuration file. There's no special munging needed
|
@@ -153,10 +150,11 @@ module Bolt
|
|
153
150
|
def self.load_bolt_yaml(dir)
|
154
151
|
filepath = dir + BOLT_CONFIG_NAME
|
155
152
|
data = Bolt::Util.read_yaml_hash(filepath, 'config')
|
156
|
-
|
157
|
-
"
|
153
|
+
deprecations = [{ type: 'Using bolt.yaml for system configuration',
|
154
|
+
msg: "Configuration file #{filepath} is deprecated and will be removed in a future version "\
|
155
|
+
"of Bolt. Use '#{dir + BOLT_DEFAULTS_NAME}' instead." }]
|
158
156
|
|
159
|
-
{ filepath: filepath, data: data, warnings:
|
157
|
+
{ filepath: filepath, data: data, warnings: [], deprecations: deprecations }
|
160
158
|
end
|
161
159
|
|
162
160
|
def self.load_defaults(project)
|
@@ -187,12 +185,16 @@ module Bolt
|
|
187
185
|
|
188
186
|
def initialize(project, config_data, overrides = {})
|
189
187
|
unless config_data.is_a?(Array)
|
190
|
-
config_data = [{ filepath: project.config_file,
|
188
|
+
config_data = [{ filepath: project.config_file,
|
189
|
+
data: config_data,
|
190
|
+
warnings: [],
|
191
|
+
deprecations: [] }]
|
191
192
|
end
|
192
193
|
|
193
194
|
@logger = Logging.logger[self]
|
194
195
|
@project = project
|
195
196
|
@warnings = @project.warnings.dup
|
197
|
+
@deprecations = @project.deprecations.dup
|
196
198
|
@transports = {}
|
197
199
|
@config_files = []
|
198
200
|
|
@@ -213,6 +215,7 @@ module Bolt
|
|
213
215
|
|
214
216
|
loaded_data = config_data.each_with_object([]) do |data, acc|
|
215
217
|
@warnings.concat(data[:warnings]) if data[:warnings].any?
|
218
|
+
@deprecations.concat(data[:deprecations]) if data[:deprecations].any?
|
216
219
|
|
217
220
|
if data[:data].any?
|
218
221
|
@config_files.push(data[:filepath])
|
@@ -316,8 +319,8 @@ module Bolt
|
|
316
319
|
end
|
317
320
|
|
318
321
|
# Filter hashes to only include valid options
|
319
|
-
@data['apply_settings'] = @data['apply_settings'].slice(*
|
320
|
-
@data['puppetfile'] = @data['puppetfile'].slice(*
|
322
|
+
@data['apply_settings'] = @data['apply_settings'].slice(*OPTIONS['apply_settings'][:properties].keys)
|
323
|
+
@data['puppetfile'] = @data['puppetfile'].slice(*OPTIONS['puppetfile'][:properties].keys)
|
321
324
|
end
|
322
325
|
|
323
326
|
private def normalize_log(target)
|
@@ -331,7 +334,7 @@ module Bolt
|
|
331
334
|
next unless val.is_a?(Hash)
|
332
335
|
|
333
336
|
name = normalize_log(key)
|
334
|
-
acc[name] = val.slice(
|
337
|
+
acc[name] = val.slice('append', 'level')
|
335
338
|
.transform_keys(&:to_sym)
|
336
339
|
|
337
340
|
if (v = acc[name][:level])
|
@@ -383,7 +386,7 @@ module Bolt
|
|
383
386
|
raise Bolt::ValidationError, "Compilation is CPU-intensive, set concurrency less than #{compile_limit}"
|
384
387
|
end
|
385
388
|
|
386
|
-
|
389
|
+
unless %w[human json rainbow].include? format
|
387
390
|
raise Bolt::ValidationError, "Unsupported format: '#{format}'"
|
388
391
|
end
|
389
392
|
|
@@ -496,7 +499,7 @@ module Bolt
|
|
496
499
|
end
|
497
500
|
|
498
501
|
def matching_paths(paths)
|
499
|
-
|
502
|
+
Array(paths).map { |p| Dir.glob([p, casefold(p)]) }.flatten.uniq.reject { |p| Array(paths).include?(p) }
|
500
503
|
end
|
501
504
|
|
502
505
|
private def casefold(path)
|