bolt 2.15.0 → 2.20.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 (96) hide show
  1. checksums.yaml +4 -4
  2. data/bolt-modules/boltlib/lib/puppet/functions/add_facts.rb +1 -0
  3. data/bolt-modules/boltlib/lib/puppet/functions/add_to_group.rb +1 -0
  4. data/bolt-modules/boltlib/lib/puppet/functions/apply_prep.rb +20 -9
  5. data/bolt-modules/boltlib/lib/puppet/functions/catch_errors.rb +1 -0
  6. data/bolt-modules/boltlib/lib/puppet/functions/download_file.rb +123 -0
  7. data/bolt-modules/boltlib/lib/puppet/functions/facts.rb +1 -0
  8. data/bolt-modules/boltlib/lib/puppet/functions/fail_plan.rb +1 -0
  9. data/bolt-modules/boltlib/lib/puppet/functions/get_resources.rb +1 -0
  10. data/bolt-modules/boltlib/lib/puppet/functions/get_target.rb +1 -0
  11. data/bolt-modules/boltlib/lib/puppet/functions/get_targets.rb +1 -0
  12. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_fact.rb +1 -0
  13. data/bolt-modules/boltlib/lib/puppet/functions/puppetdb_query.rb +1 -0
  14. data/bolt-modules/boltlib/lib/puppet/functions/remove_from_group.rb +1 -0
  15. data/bolt-modules/boltlib/lib/puppet/functions/resolve_references.rb +1 -0
  16. data/bolt-modules/boltlib/lib/puppet/functions/resource.rb +1 -0
  17. data/bolt-modules/boltlib/lib/puppet/functions/run_command.rb +3 -0
  18. data/bolt-modules/boltlib/lib/puppet/functions/run_plan.rb +2 -1
  19. data/bolt-modules/boltlib/lib/puppet/functions/run_script.rb +7 -4
  20. data/bolt-modules/boltlib/lib/puppet/functions/run_task.rb +2 -1
  21. data/bolt-modules/boltlib/lib/puppet/functions/set_config.rb +1 -0
  22. data/bolt-modules/boltlib/lib/puppet/functions/set_feature.rb +1 -0
  23. data/bolt-modules/boltlib/lib/puppet/functions/set_resources.rb +1 -0
  24. data/bolt-modules/boltlib/lib/puppet/functions/set_var.rb +1 -0
  25. data/bolt-modules/boltlib/lib/puppet/functions/upload_file.rb +1 -0
  26. data/bolt-modules/boltlib/lib/puppet/functions/vars.rb +1 -0
  27. data/bolt-modules/boltlib/lib/puppet/functions/wait_until_available.rb +1 -0
  28. data/bolt-modules/boltlib/lib/puppet/functions/without_default_logging.rb +1 -0
  29. data/bolt-modules/boltlib/lib/puppet/functions/write_file.rb +1 -0
  30. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/do_until.rb +2 -0
  31. data/bolt-modules/ctrl/lib/puppet/functions/ctrl/sleep.rb +2 -0
  32. data/bolt-modules/file/lib/puppet/functions/file/exists.rb +1 -0
  33. data/bolt-modules/file/lib/puppet/functions/file/join.rb +2 -0
  34. data/bolt-modules/file/lib/puppet/functions/file/read.rb +2 -0
  35. data/bolt-modules/file/lib/puppet/functions/file/readable.rb +2 -0
  36. data/bolt-modules/file/lib/puppet/functions/file/write.rb +2 -0
  37. data/bolt-modules/out/lib/puppet/functions/out/message.rb +2 -0
  38. data/bolt-modules/prompt/lib/puppet/functions/prompt.rb +1 -0
  39. data/bolt-modules/system/lib/puppet/functions/system/env.rb +2 -0
  40. data/lib/bolt/applicator.rb +21 -15
  41. data/lib/bolt/apply_result.rb +1 -1
  42. data/lib/bolt/bolt_option_parser.rb +55 -20
  43. data/lib/bolt/catalog.rb +3 -2
  44. data/lib/bolt/cli.rb +116 -47
  45. data/lib/bolt/config.rb +48 -148
  46. data/lib/bolt/config/options.rb +488 -0
  47. data/lib/bolt/config/transport/base.rb +16 -16
  48. data/lib/bolt/config/transport/docker.rb +9 -23
  49. data/lib/bolt/config/transport/local.rb +6 -44
  50. data/lib/bolt/config/transport/options.rb +460 -0
  51. data/lib/bolt/config/transport/orch.rb +9 -18
  52. data/lib/bolt/config/transport/remote.rb +3 -6
  53. data/lib/bolt/config/transport/ssh.rb +74 -154
  54. data/lib/bolt/config/transport/winrm.rb +18 -47
  55. data/lib/bolt/executor.rb +15 -0
  56. data/lib/bolt/inventory/group.rb +4 -3
  57. data/lib/bolt/inventory/inventory.rb +4 -17
  58. data/lib/bolt/inventory/target.rb +18 -5
  59. data/lib/bolt/logger.rb +24 -1
  60. data/lib/bolt/outputter.rb +1 -1
  61. data/lib/bolt/outputter/rainbow.rb +14 -3
  62. data/lib/bolt/pal.rb +31 -11
  63. data/lib/bolt/pal/yaml_plan/evaluator.rb +19 -2
  64. data/lib/bolt/pal/yaml_plan/step.rb +11 -2
  65. data/lib/bolt/pal/yaml_plan/step/download.rb +38 -0
  66. data/lib/bolt/pal/yaml_plan/step/upload.rb +3 -3
  67. data/lib/bolt/plugin/module.rb +2 -4
  68. data/lib/bolt/plugin/puppetdb.rb +3 -2
  69. data/lib/bolt/project.rb +41 -44
  70. data/lib/bolt/puppetdb/client.rb +2 -0
  71. data/lib/bolt/puppetdb/config.rb +16 -0
  72. data/lib/bolt/result.rb +7 -0
  73. data/lib/bolt/shell/bash.rb +53 -45
  74. data/lib/bolt/shell/powershell.rb +23 -12
  75. data/lib/bolt/shell/powershell/snippets.rb +15 -6
  76. data/lib/bolt/transport/base.rb +24 -0
  77. data/lib/bolt/transport/docker.rb +17 -5
  78. data/lib/bolt/transport/docker/connection.rb +20 -2
  79. data/lib/bolt/transport/local/connection.rb +14 -1
  80. data/lib/bolt/transport/orch.rb +20 -0
  81. data/lib/bolt/transport/simple.rb +6 -0
  82. data/lib/bolt/transport/ssh.rb +7 -1
  83. data/lib/bolt/transport/ssh/connection.rb +9 -1
  84. data/lib/bolt/transport/ssh/exec_connection.rb +23 -2
  85. data/lib/bolt/transport/winrm/connection.rb +109 -8
  86. data/lib/bolt/util.rb +26 -11
  87. data/lib/bolt/version.rb +1 -1
  88. data/lib/bolt_server/transport_app.rb +3 -2
  89. data/lib/bolt_spec/bolt_context.rb +7 -2
  90. data/lib/bolt_spec/plans.rb +15 -2
  91. data/lib/bolt_spec/plans/action_stubs.rb +2 -1
  92. data/lib/bolt_spec/plans/action_stubs/download_stub.rb +66 -0
  93. data/lib/bolt_spec/plans/mock_executor.rb +14 -1
  94. data/lib/bolt_spec/run.rb +22 -0
  95. data/libexec/bolt_catalog +3 -2
  96. metadata +20 -29
@@ -6,13 +6,7 @@ require 'pathname'
6
6
  require 'bolt/project'
7
7
  require 'bolt/logger'
8
8
  require 'bolt/util'
9
- # Transport config objects
10
- require 'bolt/config/transport/ssh'
11
- require 'bolt/config/transport/winrm'
12
- require 'bolt/config/transport/orch'
13
- require 'bolt/config/transport/local'
14
- require 'bolt/config/transport/docker'
15
- require 'bolt/config/transport/remote'
9
+ require 'bolt/config/options'
16
10
 
17
11
  module Bolt
18
12
  class UnknownTransportError < Bolt::Error
@@ -23,134 +17,18 @@ module Bolt
23
17
  end
24
18
 
25
19
  class Config
26
- attr_reader :config_files, :warnings, :data, :transports, :project, :modified_concurrency
20
+ include Bolt::Config::Options
21
+
22
+ attr_reader :config_files, :warnings, :data, :transports, :project, :modified_concurrency, :deprecations
27
23
 
28
24
  BOLT_CONFIG_NAME = 'bolt.yaml'
29
25
  BOLT_DEFAULTS_NAME = 'bolt-defaults.yaml'
30
26
 
31
- # Transport config classes. Used to load default transport config which
32
- # gets passed along to the inventory.
33
- TRANSPORT_CONFIG = {
34
- 'ssh' => Bolt::Config::Transport::SSH,
35
- 'winrm' => Bolt::Config::Transport::WinRM,
36
- 'pcp' => Bolt::Config::Transport::Orch,
37
- 'local' => Bolt::Config::Transport::Local,
38
- 'docker' => Bolt::Config::Transport::Docker,
39
- 'remote' => Bolt::Config::Transport::Remote
40
- }.freeze
41
-
42
- # Options that configure Bolt. These options are used in bolt.yaml and
43
- # bolt-defaults.yaml.
44
- BOLT_CONFIG = {
45
- "color" => "Whether to use colored output when printing messages to the console.",
46
- "compile-concurrency" => "The maximum number of simultaneous manifest block compiles.",
47
- "concurrency" => "The number of threads to use when executing on remote targets.",
48
- "format" => "The format to use when printing results. Options are `human` and `json`.",
49
- "plugin_hooks" => "Which plugins a specific hook should use.",
50
- "plugins" => "A map of plugins and their configuration data.",
51
- "puppetdb" => "A map containing options for configuring the Bolt PuppetDB client.",
52
- "puppetfile" => "A map containing options for the `bolt puppetfile install` command.",
53
- "save-rerun" => "Whether to update `.rerun.json` in the Bolt project directory. If "\
54
- "your target names include passwords, set this value to `false` to avoid "\
55
- "writing passwords to disk."
56
- }.freeze
57
-
58
- # These options are only available to bolt-defaults.yaml.
59
- DEFAULTS_CONFIG = {
60
- "inventory-config" => "A map of default configuration options for the inventory. This includes options "\
61
- "for setting the default transport to use when connecting to targets, as well as "\
62
- "options for configuring the default behavior of each transport."
63
- }.freeze
64
-
65
- # Options that configure the inventory, specifically the default transport
66
- # used by targets and the transports themselves. These options are used in
67
- # bolt.yaml, inventory.yaml, and under the inventory-config key in
68
- # bolt-defaults.yaml.
69
- INVENTORY_CONFIG = {
70
- "transport" => "The default transport to use when the transport for a target is not specified in the URI.",
71
- "docker" => "A map of configuration options for the docker transport.",
72
- "local" => "A map of configuration options for the local transport.",
73
- "pcp" => "A map of configuration options for the pcp transport.",
74
- "remote" => "A map of configuration options for the remote transport.",
75
- "ssh" => "A map of configuration options for the ssh transport.",
76
- "winrm" => "A map of configuration options for the winrm transport."
77
- }.freeze
78
-
79
- # Options that configure the project, such as paths to files used for a
80
- # specific project. These settings are used in bolt.yaml and bolt-project.yaml.
81
- PROJECT_CONFIG = {
82
- "apply_settings" => "A map of Puppet settings to use when applying Puppet code",
83
- "hiera-config" => "The path to your Hiera config.",
84
- "inventoryfile" => "The path to a structured data inventory file used to refer to groups of "\
85
- "targets on the command line and from plans.",
86
- "log" => "The configuration of the logfile output. Configuration can be set for "\
87
- "`console` and the path to a log file, such as `~/.puppetlabs/bolt/debug.log`.",
88
- "modulepath" => "An array of directories that Bolt loads content (e.g. plans and tasks) from.",
89
- "trusted-external-command" => "The path to an executable on the Bolt controller that can produce "\
90
- "external trusted facts. **External trusted facts are experimental in both "\
91
- "Puppet and Bolt and this API may change or be removed.**"
92
- }.freeze
93
-
94
- # A combined map of all configuration options that can be set in this class.
95
- # Includes all options except 'inventory-config', which is munged when loading
96
- # a bolt-defaults.yaml file.
97
- OPTIONS = BOLT_CONFIG.merge(INVENTORY_CONFIG).merge(PROJECT_CONFIG).freeze
98
-
99
- # Default values for select options. These do not set the default values in Bolt
100
- # and are only used for documentation.
101
- DEFAULT_OPTIONS = {
102
- "color" => true,
103
- "compile-concurrency" => "Number of cores",
104
- "concurrency" => "100 or one-seventh of the ulimit, whichever is lower",
105
- "format" => "human",
106
- "hiera-config" => "Boltdir/hiera.yaml",
107
- "inventoryfile" => "Boltdir/inventory.yaml",
108
- "modulepath" => ["Boltdir/modules", "Boltdir/site-modules", "Boltdir/site"],
109
- "save-rerun" => true,
110
- "transport" => "ssh"
111
- }.freeze
112
-
113
- PUPPETDB_OPTIONS = {
114
- "cacert" => "The path to the ca certificate for PuppetDB.",
115
- "cert" => "The path to the client certificate file to use for authentication.",
116
- "key" => "The private key for the certificate.",
117
- "server_urls" => "An array containing the PuppetDB host to connect to. Include the protocol `https` and "\
118
- "the port, which is usually `8081`. For example, `https://my-master.example.com:8081`.",
119
- "token" => "The path to the PE RBAC Token."
120
- }.freeze
121
-
122
- PUPPETFILE_OPTIONS = {
123
- "forge" => "A subsection that can have its own `proxy` setting to set an HTTP proxy for Forge operations "\
124
- "only, and a `baseurl` setting to specify a different Forge host.",
125
- "proxy" => "The HTTP proxy to use for Git and Forge operations."
126
- }.freeze
127
-
128
- LOG_OPTIONS = {
129
- "append" => "Add output to an existing log file. Available only for logs output to a "\
130
- "filepath.",
131
- "level" => "The type of information in the log. Either `debug`, `info`, `notice`, "\
132
- "`warn`, or `error`."
133
- }.freeze
134
-
135
- DEFAULT_LOG_OPTIONS = {
136
- "append" => true,
137
- "level" => "`warn` for console, `notice` for file"
138
- }.freeze
139
-
140
- APPLY_SETTINGS = {
141
- "show_diff" => "Whether to log and report a contextual diff when files are being replaced. "\
142
- "See [Puppet documentation](https://puppet.com/docs/puppet/latest/configuration.html#showdiff) "\
143
- "for details"
144
- }.freeze
145
-
146
- DEFAULT_APPLY_SETTINGS = {
147
- "show_diff" => false
148
- }.freeze
149
-
27
+ # The default concurrency value that is used when the ulimit is not low (i.e. < 700)
150
28
  DEFAULT_DEFAULT_CONCURRENCY = 100
151
29
 
152
30
  def self.default
153
- new(Bolt::Project.create_project('.'), {})
31
+ new(Bolt::Project.default_project, {})
154
32
  end
155
33
 
156
34
  def self.from_project(project, overrides = {})
@@ -163,7 +41,8 @@ module Bolt
163
41
  data = load_defaults(project).push(
164
42
  filepath: project.config_file,
165
43
  data: conf,
166
- warnings: []
44
+ warnings: [],
45
+ deprecations: []
167
46
  )
168
47
 
169
48
  new(project, data, overrides)
@@ -181,7 +60,8 @@ module Bolt
181
60
  data = load_defaults(project).push(
182
61
  filepath: project.config_file,
183
62
  data: conf,
184
- warnings: []
63
+ warnings: [],
64
+ deprecations: []
185
65
  )
186
66
 
187
67
  new(project, data, overrides)
@@ -221,18 +101,18 @@ module Bolt
221
101
  end
222
102
 
223
103
  # Remove project-specific config such as hiera-config, etc.
224
- project_config = data.slice(*PROJECT_CONFIG.keys)
104
+ project_config = data.slice(*(BOLT_PROJECT_OPTIONS - BOLT_DEFAULTS_OPTIONS))
225
105
 
226
106
  if project_config.any?
227
107
  data.reject! { |key, _| project_config.include?(key) }
228
108
  warnings.push(
229
109
  msg: "Unsupported project configuration detected in '#{filepath}': #{project_config.keys}. "\
230
- "Project configuration should be set in 'bolt-project.yaml'."
110
+ "Project configuration should be set in 'bolt-project.yaml'."
231
111
  )
232
112
  end
233
113
 
234
114
  # Remove top-level transport config such as transport, ssh, etc.
235
- transport_config = data.slice(*INVENTORY_CONFIG.keys)
115
+ transport_config = data.slice(*INVENTORY_OPTIONS.keys)
236
116
 
237
117
  if transport_config.any?
238
118
  data.reject! { |key, _| transport_config.include?(key) }
@@ -243,13 +123,26 @@ module Bolt
243
123
  )
244
124
  end
245
125
 
246
- # Move data under transport-config to top-level so it can be easily merged with
247
- # config from other sources.
126
+ # Move data under inventory-config to top-level so it can be easily merged with
127
+ # config from other sources. Error early if inventory-config is not a hash or
128
+ # has a plugin reference.
248
129
  if data.key?('inventory-config')
130
+ unless data['inventory-config'].is_a?(Hash)
131
+ raise Bolt::ValidationError,
132
+ "Option 'inventory-config' must be of type Hash, received #{data['inventory-config']} "\
133
+ "#{data['inventory-config']} (file: #{filepath})"
134
+ end
135
+
136
+ if data['inventory-config'].key?('_plugin')
137
+ raise Bolt::ValidationError,
138
+ "Found unsupported key '_plugin' for option 'inventory-config'; supported keys are "\
139
+ "'#{INVENTORY_OPTIONS.keys.join("', '")}' (file: #{filepath})"
140
+ end
141
+
249
142
  data = data.merge(data.delete('inventory-config'))
250
143
  end
251
144
 
252
- { filepath: filepath, data: data, warnings: warnings }
145
+ { filepath: filepath, data: data, warnings: warnings, deprecations: [] }
253
146
  end
254
147
 
255
148
  # Loads a 'bolt.yaml' file, the legacy configuration file. There's no special munging needed
@@ -257,10 +150,11 @@ module Bolt
257
150
  def self.load_bolt_yaml(dir)
258
151
  filepath = dir + BOLT_CONFIG_NAME
259
152
  data = Bolt::Util.read_yaml_hash(filepath, 'config')
260
- warnings = [msg: "Configuration file #{filepath} is deprecated and will be removed in a future version "\
261
- "of Bolt. Use '#{dir + BOLT_DEFAULTS_NAME}' instead."]
153
+ deprecations = [{ type: 'Using bolt.yaml for system configuration',
154
+ msg: "Configuration file #{filepath} is deprecated and will be removed in a future version "\
155
+ "of Bolt. Use '#{dir + BOLT_DEFAULTS_NAME}' instead." }]
262
156
 
263
- { filepath: filepath, data: data, warnings: warnings }
157
+ { filepath: filepath, data: data, warnings: [], deprecations: deprecations }
264
158
  end
265
159
 
266
160
  def self.load_defaults(project)
@@ -291,12 +185,16 @@ module Bolt
291
185
 
292
186
  def initialize(project, config_data, overrides = {})
293
187
  unless config_data.is_a?(Array)
294
- config_data = [{ filepath: project.config_file, data: config_data, warnings: [] }]
188
+ config_data = [{ filepath: project.config_file,
189
+ data: config_data,
190
+ warnings: [],
191
+ deprecations: [] }]
295
192
  end
296
193
 
297
194
  @logger = Logging.logger[self]
298
195
  @project = project
299
196
  @warnings = @project.warnings.dup
197
+ @deprecations = @project.deprecations.dup
300
198
  @transports = {}
301
199
  @config_files = []
302
200
 
@@ -317,6 +215,7 @@ module Bolt
317
215
 
318
216
  loaded_data = config_data.each_with_object([]) do |data, acc|
319
217
  @warnings.concat(data[:warnings]) if data[:warnings].any?
218
+ @deprecations.concat(data[:deprecations]) if data[:deprecations].any?
320
219
 
321
220
  if data[:data].any?
322
221
  @config_files.push(data[:filepath])
@@ -347,12 +246,13 @@ module Bolt
347
246
  def normalize_overrides(options)
348
247
  opts = options.transform_keys(&:to_s)
349
248
 
350
- # Pull out config options
351
- overrides = opts.slice(*OPTIONS.keys)
249
+ # Pull out config options. We need to add 'transport' as it's not part of the
250
+ # OPTIONS hash but is a valid option that can be set with the --transport CLI option
251
+ overrides = opts.slice(*OPTIONS.keys, 'transport')
352
252
 
353
253
  # Pull out transport config options
354
254
  TRANSPORT_CONFIG.each do |transport, config|
355
- overrides[transport] = opts.slice(*config.options.keys)
255
+ overrides[transport] = opts.slice(*config.options)
356
256
  end
357
257
 
358
258
  # Set console log to debug if in debug mode
@@ -419,8 +319,8 @@ module Bolt
419
319
  end
420
320
 
421
321
  # Filter hashes to only include valid options
422
- @data['apply_settings'] = @data['apply_settings'].slice(*APPLY_SETTINGS.keys)
423
- @data['puppetfile'] = @data['puppetfile'].slice(*PUPPETFILE_OPTIONS.keys)
322
+ @data['apply_settings'] = @data['apply_settings'].slice(*OPTIONS['apply_settings'][:properties].keys)
323
+ @data['puppetfile'] = @data['puppetfile'].slice(*OPTIONS['puppetfile'][:properties].keys)
424
324
  end
425
325
 
426
326
  private def normalize_log(target)
@@ -434,7 +334,7 @@ module Bolt
434
334
  next unless val.is_a?(Hash)
435
335
 
436
336
  name = normalize_log(key)
437
- acc[name] = val.slice(*LOG_OPTIONS.keys)
337
+ acc[name] = val.slice('append', 'level')
438
338
  .transform_keys(&:to_sym)
439
339
 
440
340
  if (v = acc[name][:level])
@@ -486,7 +386,7 @@ module Bolt
486
386
  raise Bolt::ValidationError, "Compilation is CPU-intensive, set concurrency less than #{compile_limit}"
487
387
  end
488
388
 
489
- if (format == 'rainbow' && Bolt::Util.windows?) || !(%w[human json rainbow].include? format)
389
+ unless %w[human json rainbow].include? format
490
390
  raise Bolt::ValidationError, "Unsupported format: '#{format}'"
491
391
  end
492
392
 
@@ -599,7 +499,7 @@ module Bolt
599
499
  end
600
500
 
601
501
  def matching_paths(paths)
602
- [*paths].map { |p| Dir.glob([p, casefold(p)]) }.flatten.uniq.reject { |p| [*paths].include?(p) }
502
+ Array(paths).map { |p| Dir.glob([p, casefold(p)]) }.flatten.uniq.reject { |p| Array(paths).include?(p) }
603
503
  end
604
504
 
605
505
  private def casefold(path)
@@ -0,0 +1,488 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bolt/config/transport/ssh'
4
+ require 'bolt/config/transport/winrm'
5
+ require 'bolt/config/transport/orch'
6
+ require 'bolt/config/transport/local'
7
+ require 'bolt/config/transport/docker'
8
+ require 'bolt/config/transport/remote'
9
+
10
+ module Bolt
11
+ class Config
12
+ module Options
13
+ # Transport config classes. Used to load default transport config which
14
+ # gets passed along to the inventory.
15
+ TRANSPORT_CONFIG = {
16
+ 'ssh' => Bolt::Config::Transport::SSH,
17
+ 'winrm' => Bolt::Config::Transport::WinRM,
18
+ 'pcp' => Bolt::Config::Transport::Orch,
19
+ 'local' => Bolt::Config::Transport::Local,
20
+ 'docker' => Bolt::Config::Transport::Docker,
21
+ 'remote' => Bolt::Config::Transport::Remote
22
+ }.freeze
23
+
24
+ # Plugin definition. This is used by the JSON schemas to indicate that an option
25
+ # accepts a plugin reference. Since this isn't used by Bolt to perform automatic
26
+ # type validation, the :type key is set to a JSON type instead of a Ruby type.
27
+ PLUGIN = {
28
+ "_plugin" => {
29
+ description: "A plugin reference.",
30
+ type: "object",
31
+ required: ["_plugin"],
32
+ properties: {
33
+ "_plugin" => {
34
+ description: "The name of the plugin.",
35
+ type: "string"
36
+ }
37
+ }
38
+ }
39
+ }.freeze
40
+
41
+ # The following constants define the various configuration options available to Bolt.
42
+ # Each constant is a hash where keys are the configuration option and values are the
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.
105
+ OPTIONS = {
106
+ "apply_settings" => {
107
+ description: "A map of Puppet settings to use when applying Puppet code using the `apply` "\
108
+ "plan function or the `bolt apply` command.",
109
+ type: Hash,
110
+ properties: {
111
+ "show_diff" => {
112
+ description: "Whether to log and report a contextual diff.",
113
+ type: [TrueClass, FalseClass],
114
+ _example: true,
115
+ _default: false
116
+ }
117
+ },
118
+ _plugin: false
119
+ },
120
+ "color" => {
121
+ description: "Whether to use colored output when printing messages to the console.",
122
+ type: [TrueClass, FalseClass],
123
+ _plugin: false,
124
+ _example: false,
125
+ _default: true
126
+ },
127
+ "compile-concurrency" => {
128
+ description: "The maximum number of simultaneous manifest block compiles.",
129
+ type: Integer,
130
+ minimum: 1,
131
+ _plugin: false,
132
+ _example: 5,
133
+ _default: "Number of cores."
134
+ },
135
+ "concurrency" => {
136
+ description: "The number of threads to use when executing on remote targets.",
137
+ type: Integer,
138
+ minimum: 1,
139
+ _plugin: false,
140
+ _example: 50,
141
+ _default: "100 or 1/7 the ulimit, whichever is lower."
142
+ },
143
+ "format" => {
144
+ description: "The format to use when printing results.",
145
+ type: String,
146
+ enum: %w[human json rainbow],
147
+ _plugin: false,
148
+ _example: "json",
149
+ _default: "human"
150
+ },
151
+ "hiera-config" => {
152
+ description: "The path to the Hiera configuration file.",
153
+ type: String,
154
+ _plugin: false,
155
+ _example: "~/.puppetlabs/bolt/hiera.yaml",
156
+ _default: "project/hiera.yaml"
157
+ },
158
+ "inventory-config" => {
159
+ description: "A map of default configuration options for the inventory. This includes options "\
160
+ "for setting the default transport to use when connecting to targets, as well as "\
161
+ "options for configuring the default behavior of each transport.",
162
+ type: Hash,
163
+ _plugin: false,
164
+ _example: {}
165
+ },
166
+ "inventoryfile" => {
167
+ description: "The path to a structured data inventory file used to refer to groups of targets on the "\
168
+ "command line and from plans. Read more about using inventory files in [Inventory "\
169
+ "files](inventory_file_v2.md).",
170
+ type: String,
171
+ _plugin: false,
172
+ _example: "~/.puppetlabs/bolt/inventory.yaml",
173
+ _default: "project/inventory.yaml"
174
+ },
175
+ "log" => {
176
+ description: "A map of configuration for the logfile output. Under `log`, you can configure log options "\
177
+ "for `console` and add configuration for individual log files, such as "\
178
+ "`~/.puppetlabs/bolt/debug.log`. Individual log files must be valid filepaths. If the log "\
179
+ "file does not exist, then Bolt will create it before logging information.",
180
+ type: Hash,
181
+ properties: {
182
+ "console" => {
183
+ description: "Configuration for logs output to the console.",
184
+ type: Hash,
185
+ properties: {
186
+ "level" => {
187
+ description: "The type of information to log.",
188
+ type: String,
189
+ enum: %w[debug error info notice warn fatal any],
190
+ _default: "warn for console, notice for file"
191
+ }
192
+ }
193
+ }
194
+ },
195
+ additionalProperties: {
196
+ description: "Configuration for the logfile output.",
197
+ type: Hash,
198
+ properties: {
199
+ "append" => {
200
+ description: "Whether to append output to an existing log file.",
201
+ type: [TrueClass, FalseClass],
202
+ _default: true
203
+ },
204
+ "level" => {
205
+ description: "The type of information to log.",
206
+ type: String,
207
+ enum: %w[debug error info notice warn fatal any],
208
+ _default: "warn for console, notice for file"
209
+ }
210
+ }
211
+ },
212
+ _plugin: false,
213
+ _example: { "console" => { "level" => "info" },
214
+ "~/logs/debug.log" => { "append" => false, "level" => "debug" } }
215
+ },
216
+ "modulepath" => {
217
+ description: "An array of directories that Bolt loads content such as plans and tasks from. Read more "\
218
+ "about modules in [Module structure](module_structure.md).",
219
+ type: [Array, String],
220
+ items: {
221
+ type: String
222
+ },
223
+ _plugin: false,
224
+ _example: ["~/.puppetlabs/bolt/modules", "~/.puppetlabs/bolt/site-modules"],
225
+ _default: ["project/modules", "project/site-modules", "project/site"]
226
+ },
227
+ "name" => {
228
+ description: "The name of the Bolt project. When this option is configured, the project is considered a "\
229
+ "[Bolt project](experimental_features.md#bolt-projects), allowing Bolt to load content from "\
230
+ "the project directory as though it were a module.",
231
+ type: String,
232
+ _plugin: false,
233
+ _example: "myproject"
234
+ },
235
+ "plans" => {
236
+ description: "A list of plan names to show in `bolt plan show` output, if they exist. This option is used "\
237
+ "to limit the visibility of plans for users of the project. For example, project authors "\
238
+ "might want to limit the visibility of plans that are bundled with Bolt or plans that should "\
239
+ "only be run as part of another plan. When this option is not configured, all plans are "\
240
+ "visible. This option does not prevent users from running plans that are not part of this "\
241
+ "list.",
242
+ type: Array,
243
+ _plugin: false,
244
+ _example: ["myproject", "myproject::foo", "myproject::bar"]
245
+ },
246
+ "plugin_hooks" => {
247
+ description: "A map of [plugin hooks](writing_plugins.md#hooks) and which plugins a hook should use. "\
248
+ "The only configurable plugin hook is `puppet_library`, which can use two possible plugins: "\
249
+ "[`puppet_agent`](https://github.com/puppetlabs/puppetlabs-puppet_agent#puppet_agentinstall) "\
250
+ "and [`task`](using_plugins.md#task).",
251
+ type: Hash,
252
+ _plugin: true,
253
+ _example: { "puppet_library" => { "plugin" => "puppet_agent", "version" => "6.15.0", "_run_as" => "root" } }
254
+ },
255
+ "plugins" => {
256
+ description: "A map of plugins and their configuration data, where each key is the name of a plugin and "\
257
+ "its value is a map of configuration data. Configurable options are specified by the plugin. "\
258
+ "Read more about configuring plugins in [Using plugins](using_plugins.md#configuring-plugins).",
259
+ type: Hash,
260
+ _plugin: true,
261
+ _example: { "pkcs7" => { "keysize" => 1024 } }
262
+ },
263
+ "puppetdb" => {
264
+ description: "A map containing options for [configuring the Bolt PuppetDB "\
265
+ "client](bolt_connect_puppetdb.md).",
266
+ type: Hash,
267
+ properties: {
268
+ "cacert" => {
269
+ description: "The path to the ca certificate for PuppetDB.",
270
+ type: String,
271
+ _example: "/etc/puppetlabs/puppet/ssl/certs/ca.pem"
272
+ },
273
+ "cert" => {
274
+ description: "The path to the client certificate file to use for authentication.",
275
+ type: String,
276
+ _example: "/etc/puppetlabs/puppet/ssl/certs/my-host.example.com.pem"
277
+ },
278
+ "connect_timeout" => {
279
+ description: "How long to wait in seconds when establishing connections with PuppetDB.",
280
+ type: Integer,
281
+ minimum: 1,
282
+ _default: 60,
283
+ _example: 120
284
+ },
285
+ "key" => {
286
+ description: "The private key for the certificate.",
287
+ type: String,
288
+ _example: "/etc/puppetlabs/puppet/ssl/private_keys/my-host.example.com.pem"
289
+ },
290
+ "read_timeout" => {
291
+ description: "How long to wait in seconds for a response from PuppetDB.",
292
+ type: Integer,
293
+ minimum: 1,
294
+ _default: 60,
295
+ _example: 120
296
+ },
297
+ "server_urls" => {
298
+ description: "An array containing the PuppetDB host to connect to. Include the protocol `https` "\
299
+ "and the port, which is usually `8081`. For example, "\
300
+ "`https://my-master.example.com:8081`.",
301
+ type: Array,
302
+ _example: ["https://puppet.example.com:8081"]
303
+ },
304
+ "token" => {
305
+ description: "The path to the PE RBAC Token.",
306
+ type: String,
307
+ _example: "~/.puppetlabs/token"
308
+ }
309
+ },
310
+ _plugin: true
311
+ },
312
+ "puppetfile" => {
313
+ description: "A map containing options for the `bolt puppetfile install` command.",
314
+ type: Hash,
315
+ properties: {
316
+ "forge" => {
317
+ description: "A subsection that can have its own `proxy` setting to set an HTTP proxy for Forge "\
318
+ "operations only, and a `baseurl` setting to specify a different Forge host.",
319
+ type: Hash,
320
+ properties: {
321
+ "baseurl" => {
322
+ description: "The URL to the Forge host.",
323
+ type: String,
324
+ format: "uri",
325
+ _example: "https://forge.example.com"
326
+ },
327
+ "proxy" => {
328
+ description: "The HTTP proxy to use for Git and Forge operations.",
329
+ type: String,
330
+ format: "uri",
331
+ _example: "https://forgeapi.example.com"
332
+ }
333
+ },
334
+ _example: { "baseurl" => "https://forge.example.com", "proxy" => "https://forgeapi.example.com" }
335
+ },
336
+ "proxy" => {
337
+ description: "The HTTP proxy to use for Git and Forge operations.",
338
+ type: String,
339
+ format: "uri",
340
+ _example: "https://forgeapi.example.com"
341
+ }
342
+ },
343
+ _plugin: false
344
+ },
345
+ "save-rerun" => {
346
+ description: "Whether to update `.rerun.json` in the Bolt project directory. If "\
347
+ "your target names include passwords, set this value to `false` to avoid "\
348
+ "writing passwords to disk.",
349
+ type: [TrueClass, FalseClass],
350
+ _plugin: false,
351
+ _example: false,
352
+ _default: true
353
+ },
354
+ "tasks" => {
355
+ description: "A list of task names to show in `bolt task show` output, if they exist. This option is used "\
356
+ "to limit the visibility of tasks for users of the project. For example, project authors "\
357
+ "might want to limit the visibility of tasks that are bundled with Bolt or plans that should "\
358
+ "only be run as part of a larger workflow. When this option is not configured, all tasks "\
359
+ "are visible. This option does not prevent users from running tasks that are not part of "\
360
+ "this list.",
361
+ type: Array,
362
+ items: {
363
+ type: String
364
+ },
365
+ _plugin: false,
366
+ _example: ["myproject", "myproject::foo", "myproject::bar"]
367
+ },
368
+ "trusted-external-command" => {
369
+ description: "The path to an executable on the Bolt controller that can produce external trusted facts. "\
370
+ "**External trusted facts are experimental in both Puppet and Bolt and this API may change or "\
371
+ "be removed.**",
372
+ type: String,
373
+ _plugin: false,
374
+ _example: "/etc/puppetlabs/facts/trusted_external.sh"
375
+ }
376
+ }.freeze
377
+
378
+ # Options that configure the inventory, specifically the default transport
379
+ # used by targets and the transports themselves. These options are used in
380
+ # bolt.yaml, under a 'config' key in inventory.yaml, and under the
381
+ # 'inventory-config' key in bolt-defaults.yaml.
382
+ INVENTORY_OPTIONS = {
383
+ "transport" => {
384
+ description: "The default transport to use when the transport for a target is not "\
385
+ "specified in the URI.",
386
+ type: String,
387
+ enum: TRANSPORT_CONFIG.keys,
388
+ _plugin: false,
389
+ _example: "winrm",
390
+ _default: "ssh"
391
+ },
392
+ "docker" => {
393
+ description: "A map of configuration options for the docker transport.",
394
+ type: Hash,
395
+ _plugin: true,
396
+ _example: { "cleanup" => false, "service-url" => "https://docker.example.com" }
397
+ },
398
+ "local" => {
399
+ description: "A map of configuration options for the local transport. The set of available options is "\
400
+ "platform dependent.",
401
+ type: Hash,
402
+ _plugin: true,
403
+ _example: { "cleanup" => false, "tmpdir" => "/tmp/bolt" }
404
+ },
405
+ "pcp" => {
406
+ description: "A map of configuration options for the pcp transport.",
407
+ type: Hash,
408
+ _plugin: true,
409
+ _example: { "job-poll-interval" => 15, "job-poll-timeout" => 30 }
410
+ },
411
+ "remote" => {
412
+ description: "A map of configuration options for the remote transport.",
413
+ type: Hash,
414
+ _plugin: true,
415
+ _example: { "run-on" => "proxy_target" }
416
+ },
417
+ "ssh" => {
418
+ description: "A map of configuration options for the ssh transport.",
419
+ type: Hash,
420
+ _plugin: true,
421
+ _example: { "password" => "hunter2!", "user" => "bolt" }
422
+ },
423
+ "winrm" => {
424
+ description: "A map of configuration options for the winrm transport.",
425
+ type: Hash,
426
+ _plugin: true,
427
+ _example: { "password" => "hunter2!", "user" => "bolt" }
428
+ }
429
+ }.freeze
430
+
431
+ # Options that are available in a bolt.yaml file
432
+ BOLT_OPTIONS = %w[
433
+ apply_settings
434
+ color
435
+ compile-concurrency
436
+ concurrency
437
+ format
438
+ hiera-config
439
+ inventoryfile
440
+ log
441
+ modulepath
442
+ plugin_hooks
443
+ plugins
444
+ puppetdb
445
+ puppetfile
446
+ save-rerun
447
+ trusted-external-command
448
+ ].freeze
449
+
450
+ # Options that are available in a bolt-defaults.yaml file
451
+ BOLT_DEFAULTS_OPTIONS = %w[
452
+ color
453
+ compile-concurrency
454
+ concurrency
455
+ format
456
+ inventory-config
457
+ log
458
+ plugin_hooks
459
+ plugins
460
+ puppetdb
461
+ puppetfile
462
+ save-rerun
463
+ ].freeze
464
+
465
+ # Options that are available in a bolt-project.yaml file
466
+ BOLT_PROJECT_OPTIONS = %w[
467
+ apply_settings
468
+ color
469
+ compile-concurrency
470
+ concurrency
471
+ format
472
+ hiera-config
473
+ inventoryfile
474
+ log
475
+ modulepath
476
+ name
477
+ plans
478
+ plugin_hooks
479
+ plugins
480
+ puppetdb
481
+ puppetfile
482
+ save-rerun
483
+ tasks
484
+ trusted-external-command
485
+ ].freeze
486
+ end
487
+ end
488
+ end