bolt 2.33.1 → 2.37.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.

Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/Puppetfile +1 -1
  3. data/bolt-modules/boltlib/lib/puppet/datatypes/applyresult.rb +1 -0
  4. data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -3
  5. data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +17 -6
  6. data/bolt-modules/boltlib/lib/puppet/functions/parallelize.rb +56 -0
  7. data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +24 -6
  8. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +27 -8
  9. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +21 -1
  10. data/bolt-modules/boltlib/lib/puppet/functions/run_task_with.rb +18 -1
  11. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +24 -6
  12. data/lib/bolt/analytics.rb +27 -8
  13. data/lib/bolt/apply_result.rb +3 -3
  14. data/lib/bolt/bolt_option_parser.rb +48 -16
  15. data/lib/bolt/cli.rb +95 -227
  16. data/lib/bolt/config.rb +145 -54
  17. data/lib/bolt/config/options.rb +76 -10
  18. data/lib/bolt/config/transport/base.rb +10 -19
  19. data/lib/bolt/config/transport/local.rb +0 -7
  20. data/lib/bolt/config/transport/options.rb +1 -1
  21. data/lib/bolt/config/transport/ssh.rb +8 -14
  22. data/lib/bolt/config/validator.rb +231 -0
  23. data/lib/bolt/error.rb +33 -3
  24. data/lib/bolt/executor.rb +92 -6
  25. data/lib/bolt/inventory/group.rb +2 -1
  26. data/lib/bolt/module_installer.rb +1 -1
  27. data/lib/bolt/module_installer/specs/forge_spec.rb +5 -4
  28. data/lib/bolt/module_installer/specs/git_spec.rb +4 -3
  29. data/lib/bolt/outputter/human.rb +21 -9
  30. data/lib/bolt/outputter/rainbow.rb +1 -1
  31. data/lib/bolt/pal.rb +19 -7
  32. data/lib/bolt/pal/yaml_plan.rb +7 -0
  33. data/lib/bolt/plan_creator.rb +160 -0
  34. data/lib/bolt/plugin.rb +42 -13
  35. data/lib/bolt/plugin/cache.rb +76 -0
  36. data/lib/bolt/plugin/module.rb +4 -4
  37. data/lib/bolt/project.rb +46 -40
  38. data/lib/bolt/project_manager.rb +199 -0
  39. data/lib/bolt/{project_migrator/config.rb → project_manager/config_migrator.rb} +43 -5
  40. data/lib/bolt/{project_migrator/inventory.rb → project_manager/inventory_migrator.rb} +5 -5
  41. data/lib/bolt/{project_migrator/base.rb → project_manager/migrator.rb} +2 -2
  42. data/lib/bolt/{project_migrator/modules.rb → project_manager/module_migrator.rb} +3 -3
  43. data/lib/bolt/puppetdb/client.rb +3 -2
  44. data/lib/bolt/puppetdb/config.rb +9 -8
  45. data/lib/bolt/rerun.rb +1 -5
  46. data/lib/bolt/shell/bash.rb +8 -2
  47. data/lib/bolt/shell/powershell.rb +17 -1
  48. data/lib/bolt/task/run.rb +1 -1
  49. data/lib/bolt/transport/orch.rb +0 -5
  50. data/lib/bolt/transport/orch/connection.rb +10 -3
  51. data/lib/bolt/transport/remote.rb +1 -1
  52. data/lib/bolt/transport/ssh/exec_connection.rb +6 -2
  53. data/lib/bolt/util.rb +41 -7
  54. data/lib/bolt/version.rb +1 -1
  55. data/lib/bolt/yarn.rb +23 -0
  56. data/lib/bolt_server/base_config.rb +3 -1
  57. data/lib/bolt_server/config.rb +3 -1
  58. data/lib/bolt_server/file_cache.rb +2 -0
  59. data/lib/bolt_server/plugin.rb +13 -0
  60. data/lib/bolt_server/plugin/puppet_connect_data.rb +37 -0
  61. data/lib/bolt_server/schemas/connect-data.json +22 -0
  62. data/lib/bolt_server/schemas/partials/task.json +2 -2
  63. data/lib/bolt_server/transport_app.rb +72 -13
  64. data/lib/bolt_spec/plans/mock_executor.rb +4 -1
  65. data/libexec/apply_catalog.rb +1 -1
  66. data/libexec/custom_facts.rb +1 -1
  67. data/libexec/query_resources.rb +1 -1
  68. metadata +15 -13
  69. data/lib/bolt/project_migrator.rb +0 -80
@@ -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/config/validator'
10
11
 
11
12
  module Bolt
12
13
  class UnknownTransportError < Bolt::Error
@@ -32,53 +33,97 @@ 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
+ 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
59
 
44
60
  data = load_defaults(project).push(
45
- filepath: project.config_file,
46
- data: conf,
47
- logs: logs,
48
- deprecations: []
61
+ filepath: project.config_file,
62
+ data: conf,
63
+ logs: logs,
64
+ deprecations: deprecations
49
65
  )
50
66
 
51
67
  new(project, data, overrides)
52
68
  end
53
69
 
54
70
  def self.from_file(configfile, overrides = {})
55
- project = Bolt::Project.create_project(Pathname.new(configfile).expand_path.dirname)
56
- logs = []
71
+ project = Bolt::Project.create_project(Pathname.new(configfile).expand_path.dirname)
72
+ logs = []
73
+ deprecations = []
57
74
 
58
75
  conf = if project.project_file == project.config_file
59
76
  project.data
60
77
  else
61
78
  c = Bolt::Util.read_yaml_hash(configfile, 'config')
79
+
80
+ # Validate the config against the schema. This will raise a single error
81
+ # with all validation errors.
82
+ Validator.new.tap do |validator|
83
+ validator.validate(c, bolt_schema, project.config_file.to_s)
84
+
85
+ validator.warnings.each { |warning| logs << { warn: warning } }
86
+
87
+ validator.deprecations.each do |dep|
88
+ deprecations << { type: "#{BOLT_CONFIG_NAME} #{dep[:option]}", msg: dep[:message] }
89
+ end
90
+ end
91
+
62
92
  logs << { debug: "Loaded configuration from #{configfile}" }
63
93
  c
64
94
  end
65
95
 
66
96
  data = load_defaults(project).push(
67
- filepath: configfile,
68
- data: conf,
69
- logs: logs,
70
- deprecations: []
97
+ filepath: configfile,
98
+ data: conf,
99
+ logs: logs,
100
+ deprecations: deprecations
71
101
  )
72
102
 
73
103
  new(project, data, overrides)
74
104
  end
75
105
 
76
- def self.system_path
77
- # Lazy-load expensive gem code
78
- require 'win32/dir' if Bolt::Util.windows?
106
+ def self.defaults_schema
107
+ base = OPTIONS.slice(*BOLT_DEFAULTS_OPTIONS)
108
+ inventory = 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
79
111
 
112
+ base['inventory-config'][:properties] = inventory
113
+ base
114
+ end
115
+
116
+ def self.bolt_schema
117
+ inventory = INVENTORY_OPTIONS.each_with_object({}) do |(option, definition), acc|
118
+ acc[option] = TRANSPORT_CONFIG.key?(option) ? definition.merge(TRANSPORT_CONFIG[option].schema) : definition
119
+ end
120
+
121
+ OPTIONS.slice(*BOLT_OPTIONS).merge(inventory)
122
+ end
123
+
124
+ def self.system_path
80
125
  if Bolt::Util.windows?
81
- Pathname.new(File.join(Dir::COMMON_APPDATA, 'PuppetLabs', 'bolt', 'etc'))
126
+ Pathname.new(File.join(ENV['ALLUSERSPROFILE'], 'PuppetLabs', 'bolt', 'etc'))
82
127
  else
83
128
  Pathname.new(File.join('/etc', 'puppetlabs', 'bolt'))
84
129
  end
@@ -94,9 +139,10 @@ module Bolt
94
139
  # projects. This file does not allow project-specific configuration such as 'hiera-config' and
95
140
  # 'inventoryfile', and nests all default inventory configuration under an 'inventory-config' key.
96
141
  def self.load_bolt_defaults_yaml(dir)
97
- filepath = dir + BOLT_DEFAULTS_NAME
98
- data = Bolt::Util.read_yaml_hash(filepath, 'config')
99
- logs = [{ debug: "Loaded configuration from #{filepath}" }]
142
+ filepath = dir + BOLT_DEFAULTS_NAME
143
+ data = Bolt::Util.read_yaml_hash(filepath, 'config')
144
+ logs = [{ debug: "Loaded configuration from #{filepath}" }]
145
+ deprecations = []
100
146
 
101
147
  # Warn if 'bolt.yaml' detected in same directory.
102
148
  if File.exist?(bolt_yaml = dir + BOLT_CONFIG_NAME)
@@ -106,6 +152,18 @@ module Bolt
106
152
  )
107
153
  end
108
154
 
155
+ # Validate the config against the schema. This will raise a single error
156
+ # with all validation errors.
157
+ Validator.new.tap do |validator|
158
+ validator.validate(data, defaults_schema, filepath)
159
+
160
+ validator.warnings.each { |warning| logs << { warn: warning } }
161
+
162
+ validator.deprecations.each do |dep|
163
+ deprecations << { type: "#{BOLT_DEFAULTS_NAME} #{dep[:option]}", msg: dep[:message] }
164
+ end
165
+ end
166
+
109
167
  # Remove project-specific config such as hiera-config, etc.
110
168
  project_config = data.slice(*(BOLT_PROJECT_OPTIONS - BOLT_DEFAULTS_OPTIONS))
111
169
 
@@ -148,18 +206,30 @@ module Bolt
148
206
  data = data.merge(data.delete('inventory-config'))
149
207
  end
150
208
 
151
- { filepath: filepath, data: data, logs: logs, deprecations: [] }
209
+ { filepath: filepath, data: data, logs: logs, deprecations: deprecations }
152
210
  end
153
211
 
154
212
  # Loads a 'bolt.yaml' file, the legacy configuration file. There's no special munging needed
155
213
  # here since Bolt::Config will just ignore any invalid keys.
156
214
  def self.load_bolt_yaml(dir)
157
- filepath = dir + BOLT_CONFIG_NAME
158
- data = Bolt::Util.read_yaml_hash(filepath, 'config')
159
- logs = [{ debug: "Loaded configuration from #{filepath}" }]
215
+ filepath = dir + BOLT_CONFIG_NAME
216
+ data = Bolt::Util.read_yaml_hash(filepath, 'config')
217
+ logs = [{ debug: "Loaded configuration from #{filepath}" }]
160
218
  deprecations = [{ type: 'Using bolt.yaml for system configuration',
161
- msg: "Configuration file #{filepath} is deprecated and will be removed in a future version "\
162
- "of Bolt. Use '#{dir + BOLT_DEFAULTS_NAME}' instead." }]
219
+ msg: "Configuration file #{filepath} is deprecated and will be removed in Bolt 3.0. "\
220
+ "See https://pup.pt/update-bolt-config for how to update to the latest Bolt practices." }]
221
+
222
+ # Validate the config against the schema. This will raise a single error
223
+ # with all validation errors.
224
+ Validator.new.tap do |validator|
225
+ validator.validate(data, bolt_schema, filepath)
226
+
227
+ validator.warnings.each { |warning| logs << { warn: warning } }
228
+
229
+ validator.deprecations.each do |dep|
230
+ deprecations << { type: "#{BOLT_CONFIG_NAME} #{dep[:option]}", msg: dep[:message] }
231
+ end
232
+ end
163
233
 
164
234
  { filepath: filepath, data: data, logs: logs, deprecations: deprecations }
165
235
  end
@@ -206,12 +276,14 @@ module Bolt
206
276
  @config_files = []
207
277
 
208
278
  default_data = {
279
+ 'apply-settings' => {},
209
280
  'apply_settings' => {},
210
281
  'color' => true,
211
282
  'compile-concurrency' => Etc.nprocessors,
212
283
  'concurrency' => default_concurrency,
213
284
  'format' => 'human',
214
285
  'log' => { 'console' => {} },
286
+ 'plugin-hooks' => {},
215
287
  'plugin_hooks' => {},
216
288
  'plugins' => {},
217
289
  'puppetdb' => {},
@@ -271,7 +343,7 @@ module Bolt
271
343
 
272
344
  # Set console log to debug if in debug mode
273
345
  if options[:debug]
274
- overrides['log'] = { 'console' => { 'level' => :debug } }
346
+ overrides['log'] = { 'console' => { 'level' => 'debug' } }
275
347
  end
276
348
 
277
349
  if options[:puppetfile_path]
@@ -280,6 +352,9 @@ module Bolt
280
352
 
281
353
  overrides['trace'] = opts['trace'] if opts.key?('trace')
282
354
 
355
+ # Validate the overrides
356
+ Validator.new.validate(overrides, OPTIONS, 'command line')
357
+
283
358
  overrides
284
359
  end
285
360
 
@@ -296,7 +371,7 @@ module Bolt
296
371
  when *TRANSPORT_CONFIG.keys
297
372
  Bolt::Util.deep_merge(val1, val2)
298
373
  # Hash values are shallow merged
299
- when 'puppetdb', 'plugin_hooks', 'apply_settings', 'log'
374
+ when 'puppetdb', 'plugin-hooks', 'plugin_hooks', 'apply-settings', 'apply_settings', 'log'
300
375
  val1.merge(val2)
301
376
  # All other values are overwritten
302
377
  else
@@ -333,8 +408,9 @@ module Bolt
333
408
  end
334
409
 
335
410
  # Filter hashes to only include valid options
336
- @data['apply_settings'] = @data['apply_settings'].slice(*OPTIONS['apply_settings'][:properties].keys)
337
- @data['puppetfile'] = @data['puppetfile'].slice(*OPTIONS['puppetfile'][:properties].keys)
411
+ %w[apply-settings apply_settings puppetfile].each do |opt|
412
+ @data[opt] = @data[opt].slice(*OPTIONS.dig(opt, :properties).keys)
413
+ end
338
414
  end
339
415
 
340
416
  private def normalize_log(target)
@@ -372,10 +448,18 @@ module Bolt
372
448
  raise Bolt::ValidationError,
373
449
  "level of log #{name} must be a String or Symbol, received #{v.class} #{v.inspect}"
374
450
  end
451
+
375
452
  unless Bolt::Logger.valid_level?(v)
376
453
  raise Bolt::ValidationError,
377
454
  "level of log #{name} must be one of #{Bolt::Logger.levels.join(', ')}; received #{v}"
378
455
  end
456
+
457
+ if v == 'notice'
458
+ @deprecations << {
459
+ type: 'notice log level',
460
+ msg: "Log level 'notice' is deprecated and will be removed in Bolt 3.0. Use 'info' instead."
461
+ }
462
+ end
379
463
  end
380
464
 
381
465
  if (v = acc[name][:append]) && v != true && v != false
@@ -397,37 +481,18 @@ module Bolt
397
481
  "is automatically appended to the modulepath and cannot be configured."
398
482
  end
399
483
 
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
484
  compile_limit = 2 * Etc.nprocessors
421
485
  unless compile_concurrency < compile_limit
422
486
  raise Bolt::ValidationError, "Compilation is CPU-intensive, set concurrency less than #{compile_limit}"
423
487
  end
424
488
 
425
- unless %w[human json rainbow].include? format
426
- raise Bolt::ValidationError, "Unsupported format: '#{format}'"
489
+ %w[hiera-config trusted-external-command inventoryfile].each do |opt|
490
+ Bolt::Util.validate_file(opt, @data[opt]) if @data[opt]
427
491
  end
428
492
 
429
- Bolt::Util.validate_file('hiera-config', @data['hiera-config']) if @data['hiera-config']
430
- Bolt::Util.validate_file('trusted-external-command', trusted_external) if trusted_external
493
+ if File.exist?(default_inventoryfile)
494
+ Bolt::Util.validate_file('inventory file', default_inventoryfile)
495
+ end
431
496
 
432
497
  unless TRANSPORT_CONFIG.include?(transport)
433
498
  raise UnknownTransportError, transport
@@ -464,6 +529,10 @@ module Bolt
464
529
  @data['modulepath'] = value
465
530
  end
466
531
 
532
+ def plugin_cache
533
+ @project.plugin_cache || @data['plugin-cache'] || {}
534
+ end
535
+
467
536
  def concurrency
468
537
  @data['concurrency']
469
538
  end
@@ -513,7 +582,18 @@ module Bolt
513
582
  end
514
583
 
515
584
  def plugin_hooks
516
- @data['plugin_hooks']
585
+ if @data['plugin-hooks'].any? && @data['plugin_hooks'].any?
586
+ Bolt::Logger.warn_once(
587
+ "plugin-hooks and plugin_hooks set",
588
+ "Detected configuration for 'plugin-hooks' and 'plugin_hooks'. Bolt will ignore 'plugin_hooks'."
589
+ )
590
+
591
+ @data['plugin-hooks']
592
+ elsif @data['plugin-hooks'].any?
593
+ @data['plugin-hooks']
594
+ else
595
+ @data['plugin_hooks']
596
+ end
517
597
  end
518
598
 
519
599
  def trusted_external
@@ -521,7 +601,18 @@ module Bolt
521
601
  end
522
602
 
523
603
  def apply_settings
524
- @data['apply_settings']
604
+ if @data['apply-settings'].any? && @data['apply_settings'].any?
605
+ Bolt::Logger.warn_once(
606
+ "apply-settings and apply_settings set",
607
+ "Detected configuration for 'apply-settings' and 'apply_settings'. Bolt will ignore 'apply_settings'."
608
+ )
609
+
610
+ @data['apply-settings']
611
+ elsif @data['apply-settings'].any?
612
+ @data['apply-settings']
613
+ else
614
+ @data['apply_settings']
615
+ end
525
616
  end
526
617
 
527
618
  def transport
@@ -33,6 +33,18 @@ 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
  }
@@ -104,6 +116,21 @@ module Bolt
104
116
  # files and is not used by Bolt to actually set default values.
105
117
  OPTIONS = {
106
118
  "apply_settings" => {
119
+ description: "A map of Puppet settings to use when applying Puppet code using the `apply` "\
120
+ "plan function or the `bolt apply` command.",
121
+ type: Hash,
122
+ properties: {
123
+ "show_diff" => {
124
+ description: "Whether to log and report a contextual diff.",
125
+ type: [TrueClass, FalseClass],
126
+ _example: true,
127
+ _default: false
128
+ }
129
+ },
130
+ _plugin: false,
131
+ _deprecation: "This option will be removed in Bolt 3.0. Use `apply-settings` instead."
132
+ },
133
+ "apply-settings" => {
107
134
  description: "A map of Puppet settings to use when applying Puppet code using the `apply` "\
108
135
  "plan function or the `bolt apply` command.",
109
136
  type: Hash,
@@ -169,9 +196,26 @@ module Bolt
169
196
  "files](inventory_file_v2.md).",
170
197
  type: String,
171
198
  _plugin: false,
199
+ _deprecation: "This option will be removed in Bolt 3.0. Use the `--inventoryfile` command-line option "\
200
+ "to use a non-default inventory file or move the file contents to `inventory.yaml` in the "\
201
+ "project directory.",
172
202
  _example: "~/.puppetlabs/bolt/inventory.yaml",
173
203
  _default: "project/inventory.yaml"
174
204
  },
205
+ "plugin-cache" => {
206
+ description: "This feature is experimental. Enable plugin caching and set the time-to-live.",
207
+ type: Hash,
208
+ required: ["ttl"],
209
+ properties: {
210
+ "ttl" => {
211
+ description: "Time in seconds to keep the plugin cache.",
212
+ type: Integer,
213
+ minimum: 0
214
+ }
215
+ },
216
+ _plugin: false,
217
+ _example: { "ttl" => 3600 }
218
+ },
175
219
  "log" => {
176
220
  description: "A map of configuration for the logfile output. Under `log`, you can configure log options "\
177
221
  "for `console` and add configuration for individual log files, such as "\
@@ -183,12 +227,13 @@ module Bolt
183
227
  properties: {
184
228
  "console" => {
185
229
  description: "Configuration for logs output to the console.",
186
- type: Hash,
230
+ type: [String, Hash],
231
+ enum: ['disable'],
187
232
  properties: {
188
233
  "level" => {
189
234
  description: "The type of information to log.",
190
235
  type: String,
191
- enum: %w[trace debug error info warn fatal any],
236
+ enum: %w[trace debug error info notice warn fatal any],
192
237
  _default: "warn"
193
238
  }
194
239
  }
@@ -207,7 +252,7 @@ module Bolt
207
252
  "level" => {
208
253
  description: "The type of information to log.",
209
254
  type: String,
210
- enum: %w[trace debug error info warn fatal any],
255
+ enum: %w[trace debug error info notice warn fatal any],
211
256
  _default: "warn"
212
257
  }
213
258
  }
@@ -276,14 +321,14 @@ module Bolt
276
321
  },
277
322
  "name" => {
278
323
  description: "The name of the Bolt project. When this option is configured, the project is considered a "\
279
- "[Bolt project](experimental_features.md#bolt-projects), allowing Bolt to load content from "\
280
- "the project directory as though it were a module.",
324
+ "[Bolt project](projects.md), allowing Bolt to load content from the project directory "\
325
+ "as though it were a module.",
281
326
  type: String,
282
327
  _plugin: false,
283
328
  _example: "myproject"
284
329
  },
285
330
  "plans" => {
286
- description: "A list of plan names to show in `bolt plan show` output, if they exist. This option is used "\
331
+ description: "A list of plan names and glob patterns to filter the project's plans by. This option is used "\
287
332
  "to limit the visibility of plans for users of the project. For example, project authors "\
288
333
  "might want to limit the visibility of plans that are bundled with Bolt or plans that should "\
289
334
  "only be run as part of another plan. When this option is not configured, all plans are "\
@@ -291,9 +336,19 @@ module Bolt
291
336
  "list.",
292
337
  type: Array,
293
338
  _plugin: false,
294
- _example: ["myproject", "myproject::foo", "myproject::bar"]
339
+ _example: ["myproject", "myproject::foo", "myproject::bar", "myproject::deploy::*"]
295
340
  },
296
341
  "plugin_hooks" => {
342
+ description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. "\
343
+ "The only configurable plugin hook is `puppet_library`, which can use two possible plugins: "\
344
+ "[`puppet_agent`](https://github.com/puppetlabs/puppetlabs-puppet_agent#puppet_agentinstall) "\
345
+ "and [`task`](using_plugins.md#task).",
346
+ type: Hash,
347
+ _plugin: true,
348
+ _example: { "puppet_library" => { "plugin" => "puppet_agent", "version" => "6.15.0", "_run_as" => "root" } },
349
+ _deprecation: "This option will be removed in Bolt 3.0. Use `plugin-hooks` instead."
350
+ },
351
+ "plugin-hooks" => {
297
352
  description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. "\
298
353
  "The only configurable plugin hook is `puppet_library`, which can use two possible plugins: "\
299
354
  "[`puppet_agent`](https://github.com/puppetlabs/puppetlabs-puppet_agent#puppet_agentinstall) "\
@@ -307,7 +362,11 @@ module Bolt
307
362
  "its value is a map of configuration data. Configurable options are specified by the plugin. "\
308
363
  "Read more about configuring plugins in [Using plugins](using_plugins.md#configuring-plugins).",
309
364
  type: Hash,
310
- _plugin: true,
365
+ additionalProperties: {
366
+ type: Hash,
367
+ _plugin: true
368
+ },
369
+ _plugin: false,
311
370
  _example: { "pkcs7" => { "keysize" => 1024 } }
312
371
  },
313
372
  "puppetdb" => {
@@ -402,7 +461,7 @@ module Bolt
402
461
  _default: true
403
462
  },
404
463
  "tasks" => {
405
- description: "A list of task names to show in `bolt task show` output, if they exist. This option is used "\
464
+ description: "A list of task names and glob patterns to filter the project's tasks by. This option is used "\
406
465
  "to limit the visibility of tasks for users of the project. For example, project authors "\
407
466
  "might want to limit the visibility of tasks that are bundled with Bolt or plans that should "\
408
467
  "only be run as part of a larger workflow. When this option is not configured, all tasks "\
@@ -413,7 +472,7 @@ module Bolt
413
472
  type: String
414
473
  },
415
474
  _plugin: false,
416
- _example: ["myproject", "myproject::foo", "myproject::bar"]
475
+ _example: ["myproject", "myproject::foo", "myproject::bar", "myproject::deploy_*"]
417
476
  },
418
477
  "trusted-external-command" => {
419
478
  description: "The path to an executable on the Bolt controller that can produce external trusted facts. "\
@@ -480,6 +539,7 @@ module Bolt
480
539
 
481
540
  # Options that are available in a bolt.yaml file
482
541
  BOLT_OPTIONS = %w[
542
+ apply-settings
483
543
  apply_settings
484
544
  color
485
545
  compile-concurrency
@@ -489,6 +549,7 @@ module Bolt
489
549
  inventoryfile
490
550
  log
491
551
  modulepath
552
+ plugin-hooks
492
553
  plugin_hooks
493
554
  plugins
494
555
  puppetdb
@@ -505,6 +566,8 @@ module Bolt
505
566
  format
506
567
  inventory-config
507
568
  log
569
+ plugin-cache
570
+ plugin-hooks
508
571
  plugin_hooks
509
572
  plugins
510
573
  puppetdb
@@ -514,6 +577,7 @@ module Bolt
514
577
 
515
578
  # Options that are available in a bolt-project.yaml file
516
579
  BOLT_PROJECT_OPTIONS = %w[
580
+ apply-settings
517
581
  apply_settings
518
582
  color
519
583
  compile-concurrency
@@ -526,6 +590,8 @@ module Bolt
526
590
  modules
527
591
  name
528
592
  plans
593
+ plugin-cache
594
+ plugin-hooks
529
595
  plugin_hooks
530
596
  plugins
531
597
  puppetdb