bolt 2.35.0 → 2.40.2
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/lib/bolt/analytics.rb +27 -8
- data/lib/bolt/apply_result.rb +3 -3
- data/lib/bolt/bolt_option_parser.rb +45 -18
- data/lib/bolt/cli.rb +92 -110
- data/lib/bolt/config.rb +184 -80
- data/lib/bolt/config/options.rb +144 -83
- 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 +11 -68
- data/lib/bolt/config/transport/ssh.rb +8 -19
- data/lib/bolt/executor.rb +5 -17
- data/lib/bolt/inventory.rb +25 -0
- data/lib/bolt/inventory/group.rb +0 -8
- 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 +20 -1
- 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/plugin.rb +41 -12
- 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} +49 -4
- data/lib/bolt/{project_migrator/inventory.rb → project_manager/inventory_migrator.rb} +3 -3
- 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 +8 -0
- data/lib/bolt/puppetdb/config.rb +1 -2
- data/lib/bolt/rerun.rb +1 -5
- data/lib/bolt/shell/bash.rb +8 -2
- data/lib/bolt/shell/powershell.rb +21 -3
- 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/ssh/exec_connection.rb +6 -2
- data/lib/bolt/util.rb +36 -7
- data/lib/bolt/validator.rb +227 -0
- data/lib/bolt/version.rb +1 -1
- data/lib/bolt_server/base_config.rb +3 -1
- data/lib/bolt_server/config.rb +3 -1
- 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 +3 -3
- data/lib/bolt_server/transport_app.rb +68 -40
- data/libexec/apply_catalog.rb +1 -1
- data/libexec/custom_facts.rb +1 -1
- data/libexec/query_resources.rb +1 -1
- metadata +23 -17
- 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
|
123
|
+
|
124
|
+
schema
|
125
|
+
end
|
79
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)
|
@@ -357,31 +448,14 @@ module Bolt
|
|
357
448
|
next if val == 'disable'
|
358
449
|
|
359
450
|
name = normalize_log(key)
|
451
|
+
acc[name] = val.slice('append', 'level').transform_keys(&:to_sym)
|
360
452
|
|
361
|
-
|
362
|
-
unless val.is_a?(Hash)
|
363
|
-
raise Bolt::ValidationError,
|
364
|
-
"config of log #{name} must be a Hash, received #{val.class} #{val.inspect}"
|
365
|
-
end
|
366
|
-
|
367
|
-
acc[name] = val.slice('append', 'level')
|
368
|
-
.transform_keys(&:to_sym)
|
453
|
+
next unless acc[name][:level] == 'notice'
|
369
454
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
end
|
375
|
-
unless Bolt::Logger.valid_level?(v)
|
376
|
-
raise Bolt::ValidationError,
|
377
|
-
"level of log #{name} must be one of #{Bolt::Logger.levels.join(', ')}; received #{v}"
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
|
-
if (v = acc[name][:append]) && v != true && v != false
|
382
|
-
raise Bolt::ValidationError,
|
383
|
-
"append flag of log #{name} must be a Boolean, received #{v.class} #{v.inspect}"
|
384
|
-
end
|
455
|
+
@deprecations << {
|
456
|
+
type: 'notice log level',
|
457
|
+
msg: "Log level 'notice' is deprecated and will be removed in Bolt 3.0. Use 'info' instead."
|
458
|
+
}
|
385
459
|
end
|
386
460
|
end
|
387
461
|
|
@@ -397,40 +471,36 @@ module Bolt
|
|
397
471
|
"is automatically appended to the modulepath and cannot be configured."
|
398
472
|
end
|
399
473
|
|
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
474
|
compile_limit = 2 * Etc.nprocessors
|
421
475
|
unless compile_concurrency < compile_limit
|
422
476
|
raise Bolt::ValidationError, "Compilation is CPU-intensive, set concurrency less than #{compile_limit}"
|
423
477
|
end
|
424
478
|
|
425
|
-
|
426
|
-
|
479
|
+
%w[hiera-config trusted-external-command inventoryfile].each do |opt|
|
480
|
+
Bolt::Util.validate_file(opt, @data[opt]) if @data[opt]
|
427
481
|
end
|
428
482
|
|
429
|
-
|
430
|
-
|
483
|
+
if File.exist?(default_inventoryfile)
|
484
|
+
Bolt::Util.validate_file('inventory file', default_inventoryfile)
|
485
|
+
end
|
431
486
|
|
432
|
-
|
433
|
-
|
487
|
+
# Warn the user how they should be using the 'puppetfile' or
|
488
|
+
# 'module-install' config options. We don't error here since these
|
489
|
+
# settings can be set at the user or system level.
|
490
|
+
if @project.modules && puppetfile_config.any? && module_install.empty?
|
491
|
+
command = Bolt::Util.powershell? ? 'Update-BoltProject' : 'bolt project migrate'
|
492
|
+
@logs << { warn: "Detected configuration for 'puppetfile'. This setting is not "\
|
493
|
+
"used when 'modules' is configured. Use 'module-install' instead. "\
|
494
|
+
"To automatically update your project configuration, run '#{command}'." }
|
495
|
+
elsif @project.modules.nil? && puppetfile_config.empty? && module_install.any?
|
496
|
+
@logs << { warn: "Detected configuration for 'module-install'. This setting is not "\
|
497
|
+
"used when 'modules' is not configured. Use 'puppetfile' instead." }
|
498
|
+
elsif @project.modules && puppetfile_config.any? && module_install.any?
|
499
|
+
@logs << { warn: "Detected configuration for 'puppetfile' and 'module-install'. Using "\
|
500
|
+
"configuration for 'module-install' because 'modules' is also configured." }
|
501
|
+
elsif @project.modules.nil? && puppetfile_config.any? && module_install.any?
|
502
|
+
@logs << { warn: "Detected configuration for 'puppetfile' and 'module-install'. Using "\
|
503
|
+
"configuration for 'puppetfile' because 'modules' is not configured." }
|
434
504
|
end
|
435
505
|
end
|
436
506
|
|
@@ -464,6 +534,10 @@ module Bolt
|
|
464
534
|
@data['modulepath'] = value
|
465
535
|
end
|
466
536
|
|
537
|
+
def plugin_cache
|
538
|
+
@project.plugin_cache || @data['plugin-cache'] || {}
|
539
|
+
end
|
540
|
+
|
467
541
|
def concurrency
|
468
542
|
@data['concurrency']
|
469
543
|
end
|
@@ -496,6 +570,10 @@ module Bolt
|
|
496
570
|
@data['save-rerun']
|
497
571
|
end
|
498
572
|
|
573
|
+
def spinner
|
574
|
+
@data['spinner']
|
575
|
+
end
|
576
|
+
|
499
577
|
def inventoryfile
|
500
578
|
@data['inventoryfile']
|
501
579
|
end
|
@@ -513,7 +591,18 @@ module Bolt
|
|
513
591
|
end
|
514
592
|
|
515
593
|
def plugin_hooks
|
516
|
-
@data['plugin_hooks']
|
594
|
+
if @data['plugin-hooks'].any? && @data['plugin_hooks'].any?
|
595
|
+
Bolt::Logger.warn_once(
|
596
|
+
"plugin-hooks and plugin_hooks set",
|
597
|
+
"Detected configuration for 'plugin-hooks' and 'plugin_hooks'. Bolt will ignore 'plugin_hooks'."
|
598
|
+
)
|
599
|
+
|
600
|
+
@data['plugin-hooks']
|
601
|
+
elsif @data['plugin-hooks'].any?
|
602
|
+
@data['plugin-hooks']
|
603
|
+
else
|
604
|
+
@data['plugin_hooks']
|
605
|
+
end
|
517
606
|
end
|
518
607
|
|
519
608
|
def trusted_external
|
@@ -521,13 +610,28 @@ module Bolt
|
|
521
610
|
end
|
522
611
|
|
523
612
|
def apply_settings
|
524
|
-
@data['apply_settings']
|
613
|
+
if @data['apply-settings'].any? && @data['apply_settings'].any?
|
614
|
+
Bolt::Logger.warn_once(
|
615
|
+
"apply-settings and apply_settings set",
|
616
|
+
"Detected configuration for 'apply-settings' and 'apply_settings'. Bolt will ignore 'apply_settings'."
|
617
|
+
)
|
618
|
+
|
619
|
+
@data['apply-settings']
|
620
|
+
elsif @data['apply-settings'].any?
|
621
|
+
@data['apply-settings']
|
622
|
+
else
|
623
|
+
@data['apply_settings']
|
624
|
+
end
|
525
625
|
end
|
526
626
|
|
527
627
|
def transport
|
528
628
|
@data['transport']
|
529
629
|
end
|
530
630
|
|
631
|
+
def module_install
|
632
|
+
@project.module_install || @data['module-install']
|
633
|
+
end
|
634
|
+
|
531
635
|
# Check if there is a case-insensitive match to the path
|
532
636
|
def check_path_case(type, paths)
|
533
637
|
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,8 +294,8 @@ 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"
|
@@ -294,6 +312,16 @@ module Bolt
|
|
294
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,6 +441,14 @@ 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
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 "\
|
@@ -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
|
},
|
@@ -461,6 +509,7 @@ module Bolt
|
|
461
509
|
"remote" => {
|
462
510
|
description: "A map of configuration options for the remote transport.",
|
463
511
|
type: Hash,
|
512
|
+
additionalProperties: true,
|
464
513
|
_plugin: true,
|
465
514
|
_example: { "run-on" => "proxy_target" }
|
466
515
|
},
|
@@ -480,6 +529,7 @@ module Bolt
|
|
480
529
|
|
481
530
|
# Options that are available in a bolt.yaml file
|
482
531
|
BOLT_OPTIONS = %w[
|
532
|
+
apply-settings
|
483
533
|
apply_settings
|
484
534
|
color
|
485
535
|
compile-concurrency
|
@@ -489,11 +539,13 @@ module Bolt
|
|
489
539
|
inventoryfile
|
490
540
|
log
|
491
541
|
modulepath
|
542
|
+
plugin-hooks
|
492
543
|
plugin_hooks
|
493
544
|
plugins
|
494
545
|
puppetdb
|
495
546
|
puppetfile
|
496
547
|
save-rerun
|
548
|
+
spinner
|
497
549
|
trusted-external-command
|
498
550
|
].freeze
|
499
551
|
|
@@ -505,15 +557,20 @@ module Bolt
|
|
505
557
|
format
|
506
558
|
inventory-config
|
507
559
|
log
|
560
|
+
module-install
|
561
|
+
plugin-cache
|
562
|
+
plugin-hooks
|
508
563
|
plugin_hooks
|
509
564
|
plugins
|
510
565
|
puppetdb
|
511
566
|
puppetfile
|
512
567
|
save-rerun
|
568
|
+
spinner
|
513
569
|
].freeze
|
514
570
|
|
515
571
|
# Options that are available in a bolt-project.yaml file
|
516
572
|
BOLT_PROJECT_OPTIONS = %w[
|
573
|
+
apply-settings
|
517
574
|
apply_settings
|
518
575
|
color
|
519
576
|
compile-concurrency
|
@@ -523,14 +580,18 @@ module Bolt
|
|
523
580
|
inventoryfile
|
524
581
|
log
|
525
582
|
modulepath
|
583
|
+
module-install
|
526
584
|
modules
|
527
585
|
name
|
528
586
|
plans
|
587
|
+
plugin-cache
|
588
|
+
plugin-hooks
|
529
589
|
plugin_hooks
|
530
590
|
plugins
|
531
591
|
puppetdb
|
532
592
|
puppetfile
|
533
593
|
save-rerun
|
594
|
+
spinner
|
534
595
|
tasks
|
535
596
|
trusted-external-command
|
536
597
|
].freeze
|