bolt 2.33.2 → 2.38.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 +1 -1
- data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +1 -0
- data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -3
- data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +17 -6
- data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +56 -0
- data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +24 -6
- data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +27 -8
- data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +21 -1
- data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +18 -1
- data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +24 -6
- data/lib/bolt/analytics.rb +27 -8
- data/lib/bolt/apply_result.rb +3 -3
- data/lib/bolt/bolt_option_parser.rb +48 -16
- data/lib/bolt/cli.rb +154 -249
- data/lib/bolt/config.rb +188 -55
- data/lib/bolt/config/options.rb +147 -87
- data/lib/bolt/config/transport/base.rb +10 -19
- data/lib/bolt/config/transport/local.rb +1 -7
- data/lib/bolt/config/transport/options.rb +10 -68
- data/lib/bolt/config/transport/ssh.rb +8 -14
- data/lib/bolt/error.rb +33 -3
- data/lib/bolt/executor.rb +92 -6
- data/lib/bolt/inventory.rb +25 -0
- data/lib/bolt/inventory/group.rb +2 -1
- data/lib/bolt/inventory/options.rb +130 -0
- data/lib/bolt/inventory/target.rb +10 -11
- data/lib/bolt/module_installer.rb +21 -13
- data/lib/bolt/module_installer/resolver.rb +1 -1
- data/lib/bolt/outputter.rb +19 -5
- data/lib/bolt/outputter/human.rb +41 -10
- data/lib/bolt/outputter/json.rb +1 -1
- data/lib/bolt/outputter/logger.rb +1 -1
- data/lib/bolt/outputter/rainbow.rb +13 -2
- data/lib/bolt/pal.rb +19 -7
- data/lib/bolt/pal/yaml_plan.rb +7 -0
- data/lib/bolt/plan_creator.rb +160 -0
- data/lib/bolt/plugin.rb +42 -13
- data/lib/bolt/plugin/cache.rb +76 -0
- data/lib/bolt/plugin/module.rb +4 -4
- data/lib/bolt/plugin/puppetdb.rb +1 -1
- data/lib/bolt/project.rb +59 -40
- data/lib/bolt/project_manager.rb +201 -0
- data/lib/bolt/{project_migrator/config.rb → project_manager/config_migrator.rb} +51 -5
- data/lib/bolt/{project_migrator/inventory.rb → project_manager/inventory_migrator.rb} +5 -5
- data/lib/bolt/{project_migrator/base.rb → project_manager/migrator.rb} +2 -2
- data/lib/bolt/{project_migrator/modules.rb → project_manager/module_migrator.rb} +5 -3
- data/lib/bolt/puppetdb/client.rb +11 -2
- data/lib/bolt/puppetdb/config.rb +9 -8
- data/lib/bolt/rerun.rb +1 -5
- data/lib/bolt/shell/bash.rb +8 -2
- data/lib/bolt/shell/powershell.rb +22 -4
- data/lib/bolt/target.rb +4 -0
- data/lib/bolt/task/run.rb +1 -1
- data/lib/bolt/transport/local.rb +13 -0
- data/lib/bolt/transport/orch.rb +0 -5
- data/lib/bolt/transport/orch/connection.rb +10 -3
- data/lib/bolt/transport/remote.rb +1 -1
- data/lib/bolt/transport/ssh/exec_connection.rb +6 -2
- data/lib/bolt/util.rb +41 -7
- data/lib/bolt/validator.rb +226 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt/yarn.rb +23 -0
- data/lib/bolt_server/base_config.rb +3 -1
- data/lib/bolt_server/config.rb +3 -1
- data/lib/bolt_server/file_cache.rb +2 -0
- data/lib/bolt_server/plugin.rb +13 -0
- data/lib/bolt_server/plugin/puppet_connect_data.rb +37 -0
- data/lib/bolt_server/schemas/connect-data.json +22 -0
- data/lib/bolt_server/schemas/partials/task.json +2 -2
- data/lib/bolt_server/transport_app.rb +82 -23
- data/lib/bolt_spec/plans/mock_executor.rb +4 -1
- data/libexec/apply_catalog.rb +1 -1
- data/libexec/custom_facts.rb +1 -1
- data/libexec/query_resources.rb +1 -1
- metadata +22 -13
- data/lib/bolt/project_migrator.rb +0 -80
data/lib/bolt/config.rb
CHANGED
@@ -7,6 +7,7 @@ require 'bolt/project'
|
|
7
7
|
require 'bolt/logger'
|
8
8
|
require 'bolt/util'
|
9
9
|
require 'bolt/config/options'
|
10
|
+
require 'bolt/validator'
|
10
11
|
|
11
12
|
module Bolt
|
12
13
|
class UnknownTransportError < Bolt::Error
|
@@ -32,53 +33,110 @@ module Bolt
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def self.from_project(project, overrides = {})
|
35
|
-
logs
|
36
|
+
logs = []
|
37
|
+
deprecations = []
|
38
|
+
|
36
39
|
conf = if project.project_file == project.config_file
|
37
40
|
project.data
|
38
41
|
else
|
39
42
|
c = Bolt::Util.read_optional_yaml_hash(project.config_file, 'config')
|
43
|
+
|
44
|
+
# Validate the config against the schema. This will raise a single error
|
45
|
+
# with all validation errors.
|
46
|
+
Bolt::Validator.new.tap do |validator|
|
47
|
+
validator.validate(c, bolt_schema, project.config_file.to_s)
|
48
|
+
|
49
|
+
validator.warnings.each { |warning| logs << { warn: warning } }
|
50
|
+
|
51
|
+
validator.deprecations.each do |dep|
|
52
|
+
deprecations << { type: "#{BOLT_CONFIG_NAME} #{dep[:option]}", msg: dep[:message] }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
40
56
|
logs << { debug: "Loaded configuration from #{project.config_file}" } if File.exist?(project.config_file)
|
41
57
|
c
|
42
58
|
end
|
43
|
-
|
44
59
|
data = load_defaults(project).push(
|
45
|
-
filepath:
|
46
|
-
data:
|
47
|
-
logs:
|
48
|
-
deprecations:
|
60
|
+
filepath: project.config_file,
|
61
|
+
data: conf,
|
62
|
+
logs: logs,
|
63
|
+
deprecations: deprecations
|
49
64
|
)
|
50
65
|
|
51
66
|
new(project, data, overrides)
|
52
67
|
end
|
53
68
|
|
54
69
|
def self.from_file(configfile, overrides = {})
|
55
|
-
project
|
56
|
-
logs
|
70
|
+
project = Bolt::Project.create_project(Pathname.new(configfile).expand_path.dirname)
|
71
|
+
logs = []
|
72
|
+
deprecations = []
|
57
73
|
|
58
74
|
conf = if project.project_file == project.config_file
|
59
75
|
project.data
|
60
76
|
else
|
61
77
|
c = Bolt::Util.read_yaml_hash(configfile, 'config')
|
78
|
+
|
79
|
+
# Validate the config against the schema. This will raise a single error
|
80
|
+
# with all validation errors.
|
81
|
+
Bolt::Validator.new.tap do |validator|
|
82
|
+
validator.validate(c, bolt_schema, project.config_file.to_s)
|
83
|
+
|
84
|
+
validator.warnings.each { |warning| logs << { warn: warning } }
|
85
|
+
|
86
|
+
validator.deprecations.each do |dep|
|
87
|
+
deprecations << { type: "#{BOLT_CONFIG_NAME} #{dep[:option]}", msg: dep[:message] }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
62
91
|
logs << { debug: "Loaded configuration from #{configfile}" }
|
63
92
|
c
|
64
93
|
end
|
65
94
|
|
66
95
|
data = load_defaults(project).push(
|
67
|
-
filepath:
|
68
|
-
data:
|
69
|
-
logs:
|
70
|
-
deprecations:
|
96
|
+
filepath: configfile,
|
97
|
+
data: conf,
|
98
|
+
logs: logs,
|
99
|
+
deprecations: deprecations
|
71
100
|
)
|
72
101
|
|
73
102
|
new(project, data, overrides)
|
74
103
|
end
|
75
104
|
|
76
|
-
|
77
|
-
|
78
|
-
|
105
|
+
# Builds a hash of definitions for transport configuration.
|
106
|
+
#
|
107
|
+
def self.transport_definitions
|
108
|
+
INVENTORY_OPTIONS.each_with_object({}) do |(option, definition), acc|
|
109
|
+
acc[option] = TRANSPORT_CONFIG.key?(option) ? definition.merge(TRANSPORT_CONFIG[option].schema) : definition
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Builds the schema for bolt-defaults.yaml used by the validator.
|
114
|
+
#
|
115
|
+
def self.defaults_schema
|
116
|
+
schema = {
|
117
|
+
type: Hash,
|
118
|
+
properties: BOLT_DEFAULTS_OPTIONS.map { |opt| [opt, _ref: opt] }.to_h,
|
119
|
+
definitions: OPTIONS.merge(transport_definitions)
|
120
|
+
}
|
121
|
+
|
122
|
+
schema[:definitions]['inventory-config'][:properties] = transport_definitions
|
79
123
|
|
124
|
+
schema
|
125
|
+
end
|
126
|
+
|
127
|
+
# Builds the schema for bolt.yaml used by the validator.
|
128
|
+
#
|
129
|
+
def self.bolt_schema
|
130
|
+
{
|
131
|
+
type: Hash,
|
132
|
+
properties: (BOLT_OPTIONS + INVENTORY_OPTIONS.keys).map { |opt| [opt, _ref: opt] }.to_h,
|
133
|
+
definitions: OPTIONS.merge(transport_definitions)
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.system_path
|
80
138
|
if Bolt::Util.windows?
|
81
|
-
Pathname.new(File.join(
|
139
|
+
Pathname.new(File.join(ENV['ALLUSERSPROFILE'], 'PuppetLabs', 'bolt', 'etc'))
|
82
140
|
else
|
83
141
|
Pathname.new(File.join('/etc', 'puppetlabs', 'bolt'))
|
84
142
|
end
|
@@ -94,9 +152,10 @@ module Bolt
|
|
94
152
|
# projects. This file does not allow project-specific configuration such as 'hiera-config' and
|
95
153
|
# 'inventoryfile', and nests all default inventory configuration under an 'inventory-config' key.
|
96
154
|
def self.load_bolt_defaults_yaml(dir)
|
97
|
-
filepath
|
98
|
-
data
|
99
|
-
logs
|
155
|
+
filepath = dir + BOLT_DEFAULTS_NAME
|
156
|
+
data = Bolt::Util.read_yaml_hash(filepath, 'config')
|
157
|
+
logs = [{ debug: "Loaded configuration from #{filepath}" }]
|
158
|
+
deprecations = []
|
100
159
|
|
101
160
|
# Warn if 'bolt.yaml' detected in same directory.
|
102
161
|
if File.exist?(bolt_yaml = dir + BOLT_CONFIG_NAME)
|
@@ -106,6 +165,18 @@ module Bolt
|
|
106
165
|
)
|
107
166
|
end
|
108
167
|
|
168
|
+
# Validate the config against the schema. This will raise a single error
|
169
|
+
# with all validation errors.
|
170
|
+
Bolt::Validator.new.tap do |validator|
|
171
|
+
validator.validate(data, defaults_schema, filepath)
|
172
|
+
|
173
|
+
validator.warnings.each { |warning| logs << { warn: warning } }
|
174
|
+
|
175
|
+
validator.deprecations.each do |dep|
|
176
|
+
deprecations << { type: "#{BOLT_DEFAULTS_NAME} #{dep[:option]}", msg: dep[:message] }
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
109
180
|
# Remove project-specific config such as hiera-config, etc.
|
110
181
|
project_config = data.slice(*(BOLT_PROJECT_OPTIONS - BOLT_DEFAULTS_OPTIONS))
|
111
182
|
|
@@ -148,18 +219,30 @@ module Bolt
|
|
148
219
|
data = data.merge(data.delete('inventory-config'))
|
149
220
|
end
|
150
221
|
|
151
|
-
{ filepath: filepath, data: data, logs: logs, deprecations:
|
222
|
+
{ filepath: filepath, data: data, logs: logs, deprecations: deprecations }
|
152
223
|
end
|
153
224
|
|
154
225
|
# Loads a 'bolt.yaml' file, the legacy configuration file. There's no special munging needed
|
155
226
|
# here since Bolt::Config will just ignore any invalid keys.
|
156
227
|
def self.load_bolt_yaml(dir)
|
157
|
-
filepath
|
158
|
-
data
|
159
|
-
logs
|
228
|
+
filepath = dir + BOLT_CONFIG_NAME
|
229
|
+
data = Bolt::Util.read_yaml_hash(filepath, 'config')
|
230
|
+
logs = [{ debug: "Loaded configuration from #{filepath}" }]
|
160
231
|
deprecations = [{ type: 'Using bolt.yaml for system configuration',
|
161
|
-
msg: "Configuration file #{filepath} is deprecated and will be removed in
|
162
|
-
"
|
232
|
+
msg: "Configuration file #{filepath} is deprecated and will be removed in Bolt 3.0. "\
|
233
|
+
"See https://pup.pt/update-bolt-config for how to update to the latest Bolt practices." }]
|
234
|
+
|
235
|
+
# Validate the config against the schema. This will raise a single error
|
236
|
+
# with all validation errors.
|
237
|
+
Bolt::Validator.new.tap do |validator|
|
238
|
+
validator.validate(data, bolt_schema, filepath)
|
239
|
+
|
240
|
+
validator.warnings.each { |warning| logs << { warn: warning } }
|
241
|
+
|
242
|
+
validator.deprecations.each do |dep|
|
243
|
+
deprecations << { type: "#{BOLT_CONFIG_NAME} #{dep[:option]}", msg: dep[:message] }
|
244
|
+
end
|
245
|
+
end
|
163
246
|
|
164
247
|
{ filepath: filepath, data: data, logs: logs, deprecations: deprecations }
|
165
248
|
end
|
@@ -206,17 +289,21 @@ module Bolt
|
|
206
289
|
@config_files = []
|
207
290
|
|
208
291
|
default_data = {
|
292
|
+
'apply-settings' => {},
|
209
293
|
'apply_settings' => {},
|
210
294
|
'color' => true,
|
211
295
|
'compile-concurrency' => Etc.nprocessors,
|
212
296
|
'concurrency' => default_concurrency,
|
213
297
|
'format' => 'human',
|
214
298
|
'log' => { 'console' => {} },
|
299
|
+
'module-install' => {},
|
300
|
+
'plugin-hooks' => {},
|
215
301
|
'plugin_hooks' => {},
|
216
302
|
'plugins' => {},
|
217
303
|
'puppetdb' => {},
|
218
304
|
'puppetfile' => {},
|
219
305
|
'save-rerun' => true,
|
306
|
+
'spinner' => true,
|
220
307
|
'transport' => 'ssh'
|
221
308
|
}
|
222
309
|
|
@@ -271,7 +358,7 @@ module Bolt
|
|
271
358
|
|
272
359
|
# Set console log to debug if in debug mode
|
273
360
|
if options[:debug]
|
274
|
-
overrides['log'] = { 'console' => { 'level' =>
|
361
|
+
overrides['log'] = { 'console' => { 'level' => 'debug' } }
|
275
362
|
end
|
276
363
|
|
277
364
|
if options[:puppetfile_path]
|
@@ -280,6 +367,9 @@ module Bolt
|
|
280
367
|
|
281
368
|
overrides['trace'] = opts['trace'] if opts.key?('trace')
|
282
369
|
|
370
|
+
# Validate the overrides
|
371
|
+
Bolt::Validator.new.validate(overrides, self.class.bolt_schema, 'command line')
|
372
|
+
|
283
373
|
overrides
|
284
374
|
end
|
285
375
|
|
@@ -296,7 +386,7 @@ module Bolt
|
|
296
386
|
when *TRANSPORT_CONFIG.keys
|
297
387
|
Bolt::Util.deep_merge(val1, val2)
|
298
388
|
# Hash values are shallow merged
|
299
|
-
when 'puppetdb', 'plugin_hooks', 'apply_settings', 'log'
|
389
|
+
when 'puppetdb', 'plugin-hooks', 'plugin_hooks', 'apply-settings', 'apply_settings', 'log'
|
300
390
|
val1.merge(val2)
|
301
391
|
# All other values are overwritten
|
302
392
|
else
|
@@ -333,8 +423,9 @@ module Bolt
|
|
333
423
|
end
|
334
424
|
|
335
425
|
# Filter hashes to only include valid options
|
336
|
-
|
337
|
-
|
426
|
+
%w[apply-settings apply_settings module-install puppetfile].each do |opt|
|
427
|
+
@data[opt] = @data[opt].slice(*OPTIONS.dig(opt, :properties).keys)
|
428
|
+
end
|
338
429
|
end
|
339
430
|
|
340
431
|
private def normalize_log(target)
|
@@ -372,10 +463,18 @@ module Bolt
|
|
372
463
|
raise Bolt::ValidationError,
|
373
464
|
"level of log #{name} must be a String or Symbol, received #{v.class} #{v.inspect}"
|
374
465
|
end
|
466
|
+
|
375
467
|
unless Bolt::Logger.valid_level?(v)
|
376
468
|
raise Bolt::ValidationError,
|
377
469
|
"level of log #{name} must be one of #{Bolt::Logger.levels.join(', ')}; received #{v}"
|
378
470
|
end
|
471
|
+
|
472
|
+
if v == 'notice'
|
473
|
+
@deprecations << {
|
474
|
+
type: 'notice log level',
|
475
|
+
msg: "Log level 'notice' is deprecated and will be removed in Bolt 3.0. Use 'info' instead."
|
476
|
+
}
|
477
|
+
end
|
379
478
|
end
|
380
479
|
|
381
480
|
if (v = acc[name][:append]) && v != true && v != false
|
@@ -397,41 +496,41 @@ module Bolt
|
|
397
496
|
"is automatically appended to the modulepath and cannot be configured."
|
398
497
|
end
|
399
498
|
|
400
|
-
keys = OPTIONS.keys - %w[plugins plugin_hooks puppetdb]
|
401
|
-
keys.each do |key|
|
402
|
-
next unless Bolt::Util.references?(@data[key])
|
403
|
-
valid_keys = TRANSPORT_CONFIG.keys + %w[plugins plugin_hooks puppetdb]
|
404
|
-
raise Bolt::ValidationError,
|
405
|
-
"Found unsupported key _plugin in config setting #{key}. Plugins are only available in "\
|
406
|
-
"#{valid_keys.join(', ')}."
|
407
|
-
end
|
408
|
-
|
409
|
-
unless concurrency.is_a?(Integer) && concurrency > 0
|
410
|
-
raise Bolt::ValidationError,
|
411
|
-
"Concurrency must be a positive Integer, received #{concurrency.class} #{concurrency}"
|
412
|
-
end
|
413
|
-
|
414
|
-
unless compile_concurrency.is_a?(Integer) && compile_concurrency > 0
|
415
|
-
raise Bolt::ValidationError,
|
416
|
-
"Compile concurrency must be a positive Integer, received #{compile_concurrency.class} "\
|
417
|
-
"#{compile_concurrency}"
|
418
|
-
end
|
419
|
-
|
420
499
|
compile_limit = 2 * Etc.nprocessors
|
421
500
|
unless compile_concurrency < compile_limit
|
422
501
|
raise Bolt::ValidationError, "Compilation is CPU-intensive, set concurrency less than #{compile_limit}"
|
423
502
|
end
|
424
503
|
|
425
|
-
|
426
|
-
|
504
|
+
%w[hiera-config trusted-external-command inventoryfile].each do |opt|
|
505
|
+
Bolt::Util.validate_file(opt, @data[opt]) if @data[opt]
|
427
506
|
end
|
428
507
|
|
429
|
-
|
430
|
-
|
508
|
+
if File.exist?(default_inventoryfile)
|
509
|
+
Bolt::Util.validate_file('inventory file', default_inventoryfile)
|
510
|
+
end
|
431
511
|
|
432
512
|
unless TRANSPORT_CONFIG.include?(transport)
|
433
513
|
raise UnknownTransportError, transport
|
434
514
|
end
|
515
|
+
|
516
|
+
# Warn the user how they should be using the 'puppetfile' or
|
517
|
+
# 'module-install' config options. We don't error here since these
|
518
|
+
# settings can be set at the user or system level.
|
519
|
+
if @project.modules && puppetfile_config.any? && module_install.empty?
|
520
|
+
command = Bolt::Util.powershell? ? 'Update-BoltProject' : 'bolt project migrate'
|
521
|
+
@logs << { warn: "Detected configuration for 'puppetfile'. This setting is not "\
|
522
|
+
"used when 'modules' is configured. Use 'module-install' instead. "\
|
523
|
+
"To automatically update your project configuration, run '#{command}'." }
|
524
|
+
elsif @project.modules.nil? && puppetfile_config.empty? && module_install.any?
|
525
|
+
@logs << { warn: "Detected configuration for 'module-install'. This setting is not "\
|
526
|
+
"used when 'modules' is not configured. Use 'puppetfile' instead." }
|
527
|
+
elsif @project.modules && puppetfile_config.any? && module_install.any?
|
528
|
+
@logs << { warn: "Detected configuration for 'puppetfile' and 'module-install'. Using "\
|
529
|
+
"configuration for 'module-install' because 'modules' is also configured." }
|
530
|
+
elsif @project.modules.nil? && puppetfile_config.any? && module_install.any?
|
531
|
+
@logs << { warn: "Detected configuration for 'puppetfile' and 'module-install'. Using "\
|
532
|
+
"configuration for 'puppetfile' because 'modules' is not configured." }
|
533
|
+
end
|
435
534
|
end
|
436
535
|
|
437
536
|
def default_inventoryfile
|
@@ -464,6 +563,10 @@ module Bolt
|
|
464
563
|
@data['modulepath'] = value
|
465
564
|
end
|
466
565
|
|
566
|
+
def plugin_cache
|
567
|
+
@project.plugin_cache || @data['plugin-cache'] || {}
|
568
|
+
end
|
569
|
+
|
467
570
|
def concurrency
|
468
571
|
@data['concurrency']
|
469
572
|
end
|
@@ -496,6 +599,10 @@ module Bolt
|
|
496
599
|
@data['save-rerun']
|
497
600
|
end
|
498
601
|
|
602
|
+
def spinner
|
603
|
+
@data['spinner']
|
604
|
+
end
|
605
|
+
|
499
606
|
def inventoryfile
|
500
607
|
@data['inventoryfile']
|
501
608
|
end
|
@@ -513,7 +620,18 @@ module Bolt
|
|
513
620
|
end
|
514
621
|
|
515
622
|
def plugin_hooks
|
516
|
-
@data['plugin_hooks']
|
623
|
+
if @data['plugin-hooks'].any? && @data['plugin_hooks'].any?
|
624
|
+
Bolt::Logger.warn_once(
|
625
|
+
"plugin-hooks and plugin_hooks set",
|
626
|
+
"Detected configuration for 'plugin-hooks' and 'plugin_hooks'. Bolt will ignore 'plugin_hooks'."
|
627
|
+
)
|
628
|
+
|
629
|
+
@data['plugin-hooks']
|
630
|
+
elsif @data['plugin-hooks'].any?
|
631
|
+
@data['plugin-hooks']
|
632
|
+
else
|
633
|
+
@data['plugin_hooks']
|
634
|
+
end
|
517
635
|
end
|
518
636
|
|
519
637
|
def trusted_external
|
@@ -521,13 +639,28 @@ module Bolt
|
|
521
639
|
end
|
522
640
|
|
523
641
|
def apply_settings
|
524
|
-
@data['apply_settings']
|
642
|
+
if @data['apply-settings'].any? && @data['apply_settings'].any?
|
643
|
+
Bolt::Logger.warn_once(
|
644
|
+
"apply-settings and apply_settings set",
|
645
|
+
"Detected configuration for 'apply-settings' and 'apply_settings'. Bolt will ignore 'apply_settings'."
|
646
|
+
)
|
647
|
+
|
648
|
+
@data['apply-settings']
|
649
|
+
elsif @data['apply-settings'].any?
|
650
|
+
@data['apply-settings']
|
651
|
+
else
|
652
|
+
@data['apply_settings']
|
653
|
+
end
|
525
654
|
end
|
526
655
|
|
527
656
|
def transport
|
528
657
|
@data['transport']
|
529
658
|
end
|
530
659
|
|
660
|
+
def module_install
|
661
|
+
@project.module_install || @data['module-install']
|
662
|
+
end
|
663
|
+
|
531
664
|
# Check if there is a case-insensitive match to the path
|
532
665
|
def check_path_case(type, paths)
|
533
666
|
return if paths.nil?
|
data/lib/bolt/config/options.rb
CHANGED
@@ -33,77 +33,42 @@ module Bolt
|
|
33
33
|
"_plugin" => {
|
34
34
|
description: "The name of the plugin.",
|
35
35
|
type: "string"
|
36
|
+
},
|
37
|
+
"_cache" => {
|
38
|
+
description: "This feature is experimental. Enable plugin caching and set a time-to-live.",
|
39
|
+
type: "object",
|
40
|
+
required: ["ttl"],
|
41
|
+
properties: {
|
42
|
+
"ttl" => {
|
43
|
+
description: "Time in seconds to keep the plugin cache.",
|
44
|
+
type: "integer",
|
45
|
+
minimum: 0
|
46
|
+
}
|
47
|
+
}
|
36
48
|
}
|
37
49
|
}
|
38
50
|
}
|
39
51
|
}.freeze
|
40
52
|
|
41
|
-
#
|
42
|
-
#
|
43
|
-
# option's definition. These options are used in multiple locations:
|
44
|
-
#
|
45
|
-
# - Automatic type validation when loading and setting configuration
|
46
|
-
# - Generating reference documentation for configuration files
|
47
|
-
# - Generating JSON schemas for configuration files
|
48
|
-
#
|
49
|
-
# Data includes keys defined by JSON Schema Draft 07 as well as some metadata used
|
50
|
-
# by Bolt to generate documentation. The following keys are used:
|
51
|
-
#
|
52
|
-
# :description String A detailed description of the option and what it does. This
|
53
|
-
# field is used in both documentation and the JSON schemas,
|
54
|
-
# and should provide as much detail as possible, including
|
55
|
-
# links to relevant documentation.
|
56
|
-
#
|
57
|
-
# :type Class The expected type of a value. These should be Ruby classes,
|
58
|
-
# as this field is used to perform automatic type validation.
|
59
|
-
# If an option can accept more than one type, this should be
|
60
|
-
# an array of types. Boolean values should set :type to
|
61
|
-
# [TrueClass, FalseClass], as Ruby does not have a single
|
62
|
-
# Boolean class.
|
63
|
-
#
|
64
|
-
# :items Hash A definition hash for items in an array. Similar to values
|
65
|
-
# for top-level options, items can have a :description, :type,
|
66
|
-
# or any other key in this list.
|
67
|
-
#
|
68
|
-
# :uniqueItems Boolean Whether or not an array should contain only unique items.
|
69
|
-
#
|
70
|
-
# :properties Hash A hash where keys are sub-options and values are definitions
|
71
|
-
# for the sub-option. Similar to values for top-level options,
|
72
|
-
# properties can have a :description, :type, or any other key
|
73
|
-
# in this list.
|
74
|
-
#
|
75
|
-
# :additionalProperties A variation of the :properties key, where the hash is a
|
76
|
-
# Hash definition for any properties not specified in :properties.
|
77
|
-
# This can be used to permit arbitrary sub-options, such as
|
78
|
-
# logs for the 'log' option.
|
79
|
-
#
|
80
|
-
# :required Array An array of properties that are required for options that
|
81
|
-
# accept Hash values.
|
82
|
-
#
|
83
|
-
# :minimum Integer The minimum integer value for an option.
|
84
|
-
#
|
85
|
-
# :enum Array An array of values that the option recognizes.
|
86
|
-
#
|
87
|
-
# :pattern String A JSON regex pattern that the option's vaue should match.
|
88
|
-
#
|
89
|
-
# :format String Requires that a string value matches a format defined by the
|
90
|
-
# JSON Schema draft.
|
91
|
-
#
|
92
|
-
# :_plugin Boolean Whether the option accepts a plugin reference. This is used
|
93
|
-
# when generating the JSON schemas to determine whether or not
|
94
|
-
# to include a reference to the _plugin definition. If :_plugin
|
95
|
-
# is set to true, the script that generates JSON schemas will
|
96
|
-
# automatically recurse through the :items and :properties keys
|
97
|
-
# and add plugin references if applicable.
|
98
|
-
#
|
99
|
-
# :_example Any An example value for the option. This is used to generate
|
100
|
-
# reference documentation for configuration files.
|
101
|
-
#
|
102
|
-
# :_default Any The documented default value for the option. This is only
|
103
|
-
# used to generate reference documentation for configuration
|
104
|
-
# files and is not used by Bolt to actually set default values.
|
53
|
+
# Definitions used to validate config options.
|
54
|
+
# https://github.com/puppetlabs/bolt/blob/main/schemas/README.md
|
105
55
|
OPTIONS = {
|
106
56
|
"apply_settings" => {
|
57
|
+
description: "A map of Puppet settings to use when applying Puppet code using the `apply` "\
|
58
|
+
"plan function or the `bolt apply` command.",
|
59
|
+
type: Hash,
|
60
|
+
properties: {
|
61
|
+
"show_diff" => {
|
62
|
+
description: "Whether to log and report a contextual diff.",
|
63
|
+
type: [TrueClass, FalseClass],
|
64
|
+
_example: true,
|
65
|
+
_default: false
|
66
|
+
}
|
67
|
+
},
|
68
|
+
_plugin: false,
|
69
|
+
_deprecation: "This option will be removed in Bolt 3.0. Use `apply-settings` instead."
|
70
|
+
},
|
71
|
+
"apply-settings" => {
|
107
72
|
description: "A map of Puppet settings to use when applying Puppet code using the `apply` "\
|
108
73
|
"plan function or the `bolt apply` command.",
|
109
74
|
type: Hash,
|
@@ -169,9 +134,26 @@ module Bolt
|
|
169
134
|
"files](inventory_file_v2.md).",
|
170
135
|
type: String,
|
171
136
|
_plugin: false,
|
137
|
+
_deprecation: "This option will be removed in Bolt 3.0. Use the `--inventoryfile` command-line option "\
|
138
|
+
"to use a non-default inventory file or move the file contents to `inventory.yaml` in the "\
|
139
|
+
"project directory.",
|
172
140
|
_example: "~/.puppetlabs/bolt/inventory.yaml",
|
173
141
|
_default: "project/inventory.yaml"
|
174
142
|
},
|
143
|
+
"plugin-cache" => {
|
144
|
+
description: "This feature is experimental. Enable plugin caching and set the time-to-live.",
|
145
|
+
type: Hash,
|
146
|
+
required: ["ttl"],
|
147
|
+
properties: {
|
148
|
+
"ttl" => {
|
149
|
+
description: "Time in seconds to keep the plugin cache.",
|
150
|
+
type: Integer,
|
151
|
+
minimum: 0
|
152
|
+
}
|
153
|
+
},
|
154
|
+
_plugin: false,
|
155
|
+
_example: { "ttl" => 3600 }
|
156
|
+
},
|
175
157
|
"log" => {
|
176
158
|
description: "A map of configuration for the logfile output. Under `log`, you can configure log options "\
|
177
159
|
"for `console` and add configuration for individual log files, such as "\
|
@@ -183,12 +165,13 @@ module Bolt
|
|
183
165
|
properties: {
|
184
166
|
"console" => {
|
185
167
|
description: "Configuration for logs output to the console.",
|
186
|
-
type: Hash,
|
168
|
+
type: [String, Hash],
|
169
|
+
enum: ['disable'],
|
187
170
|
properties: {
|
188
171
|
"level" => {
|
189
172
|
description: "The type of information to log.",
|
190
173
|
type: String,
|
191
|
-
enum: %w[trace debug error info warn fatal any],
|
174
|
+
enum: %w[trace debug error info notice warn fatal any],
|
192
175
|
_default: "warn"
|
193
176
|
}
|
194
177
|
}
|
@@ -207,7 +190,7 @@ module Bolt
|
|
207
190
|
"level" => {
|
208
191
|
description: "The type of information to log.",
|
209
192
|
type: String,
|
210
|
-
enum: %w[trace debug error info warn fatal any],
|
193
|
+
enum: %w[trace debug error info notice warn fatal any],
|
211
194
|
_default: "warn"
|
212
195
|
}
|
213
196
|
}
|
@@ -227,6 +210,41 @@ module Bolt
|
|
227
210
|
_example: ["~/.puppetlabs/bolt/modules", "~/.puppetlabs/bolt/site-modules"],
|
228
211
|
_default: ["project/modules", "project/site-modules", "project/site"]
|
229
212
|
},
|
213
|
+
"module-install" => {
|
214
|
+
description: "Options that configure where Bolt downloads modules from. This option is only used when "\
|
215
|
+
"installing modules using the `bolt module add|install` commands and "\
|
216
|
+
"`Add|Install-BoltModule` cmdlets.",
|
217
|
+
type: Hash,
|
218
|
+
properties: {
|
219
|
+
"forge" => {
|
220
|
+
description: "A subsection that can have its own `proxy` setting to set an HTTP proxy for Forge "\
|
221
|
+
"operations only, and a `baseurl` setting to specify a different Forge host.",
|
222
|
+
type: Hash,
|
223
|
+
properties: {
|
224
|
+
"baseurl" => {
|
225
|
+
description: "The URL to the Forge host.",
|
226
|
+
type: String,
|
227
|
+
format: "uri",
|
228
|
+
_example: "https://forge.example.com"
|
229
|
+
},
|
230
|
+
"proxy" => {
|
231
|
+
description: "The HTTP proxy to use for Forge operations.",
|
232
|
+
type: String,
|
233
|
+
format: "uri",
|
234
|
+
_example: "https://my-forge-proxy.com:8080"
|
235
|
+
}
|
236
|
+
},
|
237
|
+
_example: { "baseurl" => "https://forge.example.com", "proxy" => "https://my-forge-proxy.com:8080" }
|
238
|
+
},
|
239
|
+
"proxy" => {
|
240
|
+
description: "The HTTP proxy to use for Git and Forge operations.",
|
241
|
+
type: String,
|
242
|
+
format: "uri",
|
243
|
+
_example: "https://my-proxy.com:8080"
|
244
|
+
}
|
245
|
+
},
|
246
|
+
_plugin: false
|
247
|
+
},
|
230
248
|
"modules" => {
|
231
249
|
description: "A list of module dependencies for the project. Each dependency is a map of data specifying "\
|
232
250
|
"the module to install. To install the project's module dependencies, run the `bolt module "\
|
@@ -276,14 +294,14 @@ module Bolt
|
|
276
294
|
},
|
277
295
|
"name" => {
|
278
296
|
description: "The name of the Bolt project. When this option is configured, the project is considered a "\
|
279
|
-
"[Bolt project](
|
280
|
-
"
|
297
|
+
"[Bolt project](projects.md), allowing Bolt to load content from the project directory "\
|
298
|
+
"as though it were a module.",
|
281
299
|
type: String,
|
282
300
|
_plugin: false,
|
283
301
|
_example: "myproject"
|
284
302
|
},
|
285
303
|
"plans" => {
|
286
|
-
description: "A list of plan names
|
304
|
+
description: "A list of plan names and glob patterns to filter the project's plans by. This option is used "\
|
287
305
|
"to limit the visibility of plans for users of the project. For example, project authors "\
|
288
306
|
"might want to limit the visibility of plans that are bundled with Bolt or plans that should "\
|
289
307
|
"only be run as part of another plan. When this option is not configured, all plans are "\
|
@@ -291,9 +309,19 @@ module Bolt
|
|
291
309
|
"list.",
|
292
310
|
type: Array,
|
293
311
|
_plugin: false,
|
294
|
-
_example: ["myproject", "myproject::foo", "myproject::bar"]
|
312
|
+
_example: ["myproject", "myproject::foo", "myproject::bar", "myproject::deploy::*"]
|
295
313
|
},
|
296
314
|
"plugin_hooks" => {
|
315
|
+
description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. "\
|
316
|
+
"The only configurable plugin hook is `puppet_library`, which can use two possible plugins: "\
|
317
|
+
"[`puppet_agent`](https://github.com/puppetlabs/puppetlabs-puppet_agent#puppet_agentinstall) "\
|
318
|
+
"and [`task`](using_plugins.md#task).",
|
319
|
+
type: Hash,
|
320
|
+
_plugin: true,
|
321
|
+
_example: { "puppet_library" => { "plugin" => "puppet_agent", "version" => "6.15.0", "_run_as" => "root" } },
|
322
|
+
_deprecation: "This option will be removed in Bolt 3.0. Use `plugin-hooks` instead."
|
323
|
+
},
|
324
|
+
"plugin-hooks" => {
|
297
325
|
description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. "\
|
298
326
|
"The only configurable plugin hook is `puppet_library`, which can use two possible plugins: "\
|
299
327
|
"[`puppet_agent`](https://github.com/puppetlabs/puppetlabs-puppet_agent#puppet_agentinstall) "\
|
@@ -307,7 +335,11 @@ module Bolt
|
|
307
335
|
"its value is a map of configuration data. Configurable options are specified by the plugin. "\
|
308
336
|
"Read more about configuring plugins in [Using plugins](using_plugins.md#configuring-plugins).",
|
309
337
|
type: Hash,
|
310
|
-
|
338
|
+
additionalProperties: {
|
339
|
+
type: Hash,
|
340
|
+
_plugin: true
|
341
|
+
},
|
342
|
+
_plugin: false,
|
311
343
|
_example: { "pkcs7" => { "keysize" => 1024 } }
|
312
344
|
},
|
313
345
|
"puppetdb" => {
|
@@ -318,49 +350,57 @@ module Bolt
|
|
318
350
|
"cacert" => {
|
319
351
|
description: "The path to the ca certificate for PuppetDB.",
|
320
352
|
type: String,
|
321
|
-
_example: "/etc/puppetlabs/puppet/ssl/certs/ca.pem"
|
353
|
+
_example: "/etc/puppetlabs/puppet/ssl/certs/ca.pem",
|
354
|
+
_plugin: true
|
322
355
|
},
|
323
356
|
"cert" => {
|
324
357
|
description: "The path to the client certificate file to use for authentication.",
|
325
358
|
type: String,
|
326
|
-
_example: "/etc/puppetlabs/puppet/ssl/certs/my-host.example.com.pem"
|
359
|
+
_example: "/etc/puppetlabs/puppet/ssl/certs/my-host.example.com.pem",
|
360
|
+
_plugin: true
|
327
361
|
},
|
328
362
|
"connect_timeout" => {
|
329
363
|
description: "How long to wait in seconds when establishing connections with PuppetDB.",
|
330
364
|
type: Integer,
|
331
365
|
minimum: 1,
|
332
366
|
_default: 60,
|
333
|
-
_example: 120
|
367
|
+
_example: 120,
|
368
|
+
_plugin: true
|
334
369
|
},
|
335
370
|
"key" => {
|
336
371
|
description: "The private key for the certificate.",
|
337
372
|
type: String,
|
338
|
-
_example: "/etc/puppetlabs/puppet/ssl/private_keys/my-host.example.com.pem"
|
373
|
+
_example: "/etc/puppetlabs/puppet/ssl/private_keys/my-host.example.com.pem",
|
374
|
+
_plugin: true
|
339
375
|
},
|
340
376
|
"read_timeout" => {
|
341
377
|
description: "How long to wait in seconds for a response from PuppetDB.",
|
342
378
|
type: Integer,
|
343
379
|
minimum: 1,
|
344
380
|
_default: 60,
|
345
|
-
_example: 120
|
381
|
+
_example: 120,
|
382
|
+
_plugin: true
|
346
383
|
},
|
347
384
|
"server_urls" => {
|
348
385
|
description: "An array containing the PuppetDB host to connect to. Include the protocol `https` "\
|
349
386
|
"and the port, which is usually `8081`. For example, "\
|
350
387
|
"`https://my-puppetdb-server.com:8081`.",
|
351
388
|
type: Array,
|
352
|
-
_example: ["https://puppet.example.com:8081"]
|
389
|
+
_example: ["https://puppet.example.com:8081"],
|
390
|
+
_plugin: true
|
353
391
|
},
|
354
392
|
"token" => {
|
355
393
|
description: "The path to the PE RBAC Token.",
|
356
394
|
type: String,
|
357
|
-
_example: "~/.puppetlabs/token"
|
395
|
+
_example: "~/.puppetlabs/token",
|
396
|
+
_plugin: true
|
358
397
|
}
|
359
398
|
},
|
360
399
|
_plugin: true
|
361
400
|
},
|
362
401
|
"puppetfile" => {
|
363
|
-
description: "A map containing options for the `bolt puppetfile install` command
|
402
|
+
description: "A map containing options for the `bolt puppetfile install` command and "\
|
403
|
+
"`Install-BoltPuppetfile` cmdlet.",
|
364
404
|
type: Hash,
|
365
405
|
properties: {
|
366
406
|
"forge" => {
|
@@ -375,19 +415,19 @@ module Bolt
|
|
375
415
|
_example: "https://forge.example.com"
|
376
416
|
},
|
377
417
|
"proxy" => {
|
378
|
-
description: "The HTTP proxy to use for
|
418
|
+
description: "The HTTP proxy to use for Forge operations.",
|
379
419
|
type: String,
|
380
420
|
format: "uri",
|
381
|
-
_example: "https://
|
421
|
+
_example: "https://my-forge-proxy.com:8080"
|
382
422
|
}
|
383
423
|
},
|
384
|
-
_example: { "baseurl" => "https://forge.example.com", "proxy" => "https://
|
424
|
+
_example: { "baseurl" => "https://forge.example.com", "proxy" => "https://my-forge-proxy.com:8080" }
|
385
425
|
},
|
386
426
|
"proxy" => {
|
387
427
|
description: "The HTTP proxy to use for Git and Forge operations.",
|
388
428
|
type: String,
|
389
429
|
format: "uri",
|
390
|
-
_example: "https://
|
430
|
+
_example: "https://my-proxy.com:8080"
|
391
431
|
}
|
392
432
|
},
|
393
433
|
_plugin: false
|
@@ -401,8 +441,16 @@ module Bolt
|
|
401
441
|
_example: false,
|
402
442
|
_default: true
|
403
443
|
},
|
444
|
+
"spinner" => {
|
445
|
+
description: "Whether to print a spinner to the console for long-running Bolt operations.",
|
446
|
+
type: [TrueClass, FalseClass],
|
447
|
+
_plugin: false,
|
448
|
+
_example: false,
|
449
|
+
_default: true
|
450
|
+
},
|
451
|
+
|
404
452
|
"tasks" => {
|
405
|
-
description: "A list of task names
|
453
|
+
description: "A list of task names and glob patterns to filter the project's tasks by. This option is used "\
|
406
454
|
"to limit the visibility of tasks for users of the project. For example, project authors "\
|
407
455
|
"might want to limit the visibility of tasks that are bundled with Bolt or plans that should "\
|
408
456
|
"only be run as part of a larger workflow. When this option is not configured, all tasks "\
|
@@ -413,7 +461,7 @@ module Bolt
|
|
413
461
|
type: String
|
414
462
|
},
|
415
463
|
_plugin: false,
|
416
|
-
_example: ["myproject", "myproject::foo", "myproject::bar"]
|
464
|
+
_example: ["myproject", "myproject::foo", "myproject::bar", "myproject::deploy_*"]
|
417
465
|
},
|
418
466
|
"trusted-external-command" => {
|
419
467
|
description: "The path to an executable on the Bolt controller that can produce external trusted facts. "\
|
@@ -435,7 +483,7 @@ module Bolt
|
|
435
483
|
"specified in the URI.",
|
436
484
|
type: String,
|
437
485
|
enum: TRANSPORT_CONFIG.keys,
|
438
|
-
_plugin:
|
486
|
+
_plugin: true,
|
439
487
|
_example: "winrm",
|
440
488
|
_default: "ssh"
|
441
489
|
},
|
@@ -480,6 +528,7 @@ module Bolt
|
|
480
528
|
|
481
529
|
# Options that are available in a bolt.yaml file
|
482
530
|
BOLT_OPTIONS = %w[
|
531
|
+
apply-settings
|
483
532
|
apply_settings
|
484
533
|
color
|
485
534
|
compile-concurrency
|
@@ -489,11 +538,13 @@ module Bolt
|
|
489
538
|
inventoryfile
|
490
539
|
log
|
491
540
|
modulepath
|
541
|
+
plugin-hooks
|
492
542
|
plugin_hooks
|
493
543
|
plugins
|
494
544
|
puppetdb
|
495
545
|
puppetfile
|
496
546
|
save-rerun
|
547
|
+
spinner
|
497
548
|
trusted-external-command
|
498
549
|
].freeze
|
499
550
|
|
@@ -505,15 +556,20 @@ module Bolt
|
|
505
556
|
format
|
506
557
|
inventory-config
|
507
558
|
log
|
559
|
+
module-install
|
560
|
+
plugin-cache
|
561
|
+
plugin-hooks
|
508
562
|
plugin_hooks
|
509
563
|
plugins
|
510
564
|
puppetdb
|
511
565
|
puppetfile
|
512
566
|
save-rerun
|
567
|
+
spinner
|
513
568
|
].freeze
|
514
569
|
|
515
570
|
# Options that are available in a bolt-project.yaml file
|
516
571
|
BOLT_PROJECT_OPTIONS = %w[
|
572
|
+
apply-settings
|
517
573
|
apply_settings
|
518
574
|
color
|
519
575
|
compile-concurrency
|
@@ -523,14 +579,18 @@ module Bolt
|
|
523
579
|
inventoryfile
|
524
580
|
log
|
525
581
|
modulepath
|
582
|
+
module-install
|
526
583
|
modules
|
527
584
|
name
|
528
585
|
plans
|
586
|
+
plugin-cache
|
587
|
+
plugin-hooks
|
529
588
|
plugin_hooks
|
530
589
|
plugins
|
531
590
|
puppetdb
|
532
591
|
puppetfile
|
533
592
|
save-rerun
|
593
|
+
spinner
|
534
594
|
tasks
|
535
595
|
trusted-external-command
|
536
596
|
].freeze
|