Class: Bolt::Config
- Inherits:
-
Object
- Object
- Bolt::Config
- Defined in:
- lib/bolt/config.rb
Constant Summary collapse
- OPTIONS =
{ "apply_settings" => "A map of Puppet settings to use when applying Puppet code", "color" => "Whether to use colored output when printing messages to the console.", "compile-concurrency" => "The maximum number of simultaneous manifest block compiles.", "concurrency" => "The number of threads to use when executing on remote targets.", "format" => "The format to use when printing results. Options are `human` and `json`.", "hiera-config" => "The path to your Hiera config.", "inventoryfile" => "The path to a structured data inventory file used to refer to groups of "\ "targets on the command line and from plans.", "log" => "The configuration of the logfile output. Configuration can be set for "\ "`console` and the path to a log file, such as `~/.puppetlabs/bolt/debug.log`.", "modulepath" => "The module path for loading tasks and plan code. This is either an array "\ "of directories or a string containing a list of directories separated by the "\ "OS-specific PATH separator.", "plugin_hooks" => "Which plugins a specific hook should use.", "plugins" => "A map of plugins and their configuration data.", "puppetdb" => "A map containing options for configuring the Bolt PuppetDB client.", "puppetfile" => "A map containing options for the `bolt puppetfile install` command.", "save-rerun" => "Whether to update `.rerun.json` in the Bolt project directory. If "\ "your target names include passwords, set this value to `false` to avoid "\ "writing passwords to disk.", "transport" => "The default transport to use when the transport for a target is not "\ "specified in the URL or inventory.", "trusted-external-command" => "The path to an executable on the Bolt controller that can produce "\ "external trusted facts. **External trusted facts are experimental in both "\ "Puppet and Bolt and this API may change or be removed.**" }.freeze
- DEFAULT_OPTIONS =
{ "color" => true, "concurrency" => 100, "compile-concurrency" => "Number of cores", "format" => "human", "hiera-config" => "Boltdir/hiera.yaml", "inventoryfile" => "Boltdir/inventory.yaml", "modulepath" => ["Boltdir/modules", "Boltdir/site-modules", "Boltdir/site"], "save-rerun" => true }.freeze
- PUPPETFILE_OPTIONS =
{ "forge" => "A subsection that can have its own `proxy` setting to set an HTTP proxy for Forge operations "\ "only, and a `baseurl` setting to specify a different Forge host.", "proxy" => "The HTTP proxy to use for Git and Forge operations." }.freeze
- LOG_OPTIONS =
{ "append" => "Add output to an existing log file. Available only for logs output to a "\ "filepath.", "level" => "The type of information in the log. Either `debug`, `info`, `notice`, "\ "`warn`, or `error`." }.freeze
- DEFAULT_LOG_OPTIONS =
{ "append" => true, "level" => "`warn` for console, `notice` for file" }.freeze
- APPLY_SETTINGS =
{ "show_diff" => "Whether to log and report a contextual diff when files are being replaced. "\ "See [Puppet documentation](https://puppet.com/docs/puppet/latest/configuration.html#showdiff) "\ "for details" }.freeze
- DEFAULT_APPLY_SETTINGS =
{ "show_diff" => false }.freeze
Instance Attribute Summary collapse
-
#apply_settings ⇒ Object
Returns the value of attribute apply_settings.
-
#boltdir ⇒ Object
Returns the value of attribute boltdir.
-
#color ⇒ Object
Returns the value of attribute color.
-
#compile_concurrency ⇒ Object
Returns the value of attribute compile_concurrency.
-
#concurrency ⇒ Object
Returns the value of attribute concurrency.
-
#config_files ⇒ Object
readonly
Returns the value of attribute config_files.
-
#format ⇒ Object
Returns the value of attribute format.
-
#inventoryfile ⇒ Object
Returns the value of attribute inventoryfile.
-
#log ⇒ Object
Returns the value of attribute log.
- #modulepath ⇒ Object
-
#plugin_hooks ⇒ Object
Returns the value of attribute plugin_hooks.
-
#plugins ⇒ Object
Returns the value of attribute plugins.
-
#puppetdb ⇒ Object
Returns the value of attribute puppetdb.
-
#puppetfile_config ⇒ Object
Returns the value of attribute puppetfile_config.
-
#save_rerun ⇒ Object
Returns the value of attribute save_rerun.
-
#trace ⇒ Object
Returns the value of attribute trace.
-
#transport ⇒ Object
Returns the value of attribute transport.
-
#transports ⇒ Object
Returns the value of attribute transports.
-
#trusted_external ⇒ Object
Returns the value of attribute trusted_external.
-
#warnings ⇒ Object
readonly
Returns the value of attribute warnings.
Class Method Summary collapse
- .default ⇒ Object
- .from_boltdir(boltdir, overrides = {}) ⇒ Object
- .from_file(configfile, overrides = {}) ⇒ Object
- .load_defaults ⇒ Object
Instance Method Summary collapse
- #apply_overrides(options) ⇒ Object
- #casefold(path) ⇒ Object
-
#check_path_case(type, paths) ⇒ Object
Check if there is a case-insensitive match to the path.
- #deep_clone ⇒ Object
- #default_inventoryfile ⇒ Object
- #hiera_config ⇒ Object
-
#initialize(boltdir, config_data, overrides = {}) ⇒ Config
constructor
A new instance of Config.
- #matching_paths(paths) ⇒ Object
-
#merge_config_data(config_data) ⇒ Object
Merge configuration Precedence from highest to lowest is: project, user-level, system-wide.
- #normalize_interpreters(interpreters) ⇒ Object
- #normalize_log(target) ⇒ Object
- #overwrite_transport_data(transport, transports) ⇒ Object
- #puppetfile ⇒ Object
- #rerunfile ⇒ Object
- #transport_conf ⇒ Object
- #transport_data_get ⇒ Object
- #update_from_inventory(data) ⇒ Object
- #update_logs(logs) ⇒ Object
- #update_transports(data) ⇒ Object
- #validate ⇒ Object
Constructor Details
#initialize(boltdir, config_data, overrides = {}) ⇒ Config
Returns a new instance of Config.
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/bolt/config.rb', line 151 def initialize(boltdir, config_data, overrides = {}) unless config_data.is_a?(Array) config_data = [{ filepath: boltdir.config_file, data: config_data }] end @logger = Logging.logger[self] @boltdir = boltdir @concurrency = 100 @compile_concurrency = Etc.nprocessors @transport = 'ssh' @format = 'human' @puppetdb = {} @color = true @save_rerun = true @puppetfile_config = {} @plugins = {} @plugin_hooks = {} @apply_settings = {} @warnings = [] # add an entry for the default console logger @log = { 'console' => {} } @transports = {} TRANSPORTS.each do |key, transport| @transports[key] = transport. end @config_files = config_data.map { |config| config[:filepath] } config_data = merge_config_data(config_data) update_from_file(config_data) apply_overrides(overrides) validate end |
Instance Attribute Details
#apply_settings ⇒ Object
Returns the value of attribute apply_settings.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def apply_settings @apply_settings end |
#boltdir ⇒ Object
Returns the value of attribute boltdir.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def boltdir @boltdir end |
#color ⇒ Object
Returns the value of attribute color.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def color @color end |
#compile_concurrency ⇒ Object
Returns the value of attribute compile_concurrency.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def compile_concurrency @compile_concurrency end |
#concurrency ⇒ Object
Returns the value of attribute concurrency.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def concurrency @concurrency end |
#config_files ⇒ Object (readonly)
Returns the value of attribute config_files.
40 41 42 |
# File 'lib/bolt/config.rb', line 40 def config_files @config_files end |
#format ⇒ Object
Returns the value of attribute format.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def format @format end |
#inventoryfile ⇒ Object
Returns the value of attribute inventoryfile.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def inventoryfile @inventoryfile end |
#log ⇒ Object
Returns the value of attribute log.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def log @log end |
#modulepath ⇒ Object
389 390 391 |
# File 'lib/bolt/config.rb', line 389 def modulepath @modulepath || @boltdir.modulepath end |
#plugin_hooks ⇒ Object
Returns the value of attribute plugin_hooks.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def plugin_hooks @plugin_hooks end |
#plugins ⇒ Object
Returns the value of attribute plugins.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def plugins @plugins end |
#puppetdb ⇒ Object
Returns the value of attribute puppetdb.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def puppetdb @puppetdb end |
#puppetfile_config ⇒ Object
Returns the value of attribute puppetfile_config.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def puppetfile_config @puppetfile_config end |
#save_rerun ⇒ Object
Returns the value of attribute save_rerun.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def save_rerun @save_rerun end |
#trace ⇒ Object
Returns the value of attribute trace.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def trace @trace end |
#transport ⇒ Object
Returns the value of attribute transport.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def transport @transport end |
#transports ⇒ Object
Returns the value of attribute transports.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def transports @transports end |
#trusted_external ⇒ Object
Returns the value of attribute trusted_external.
35 36 37 |
# File 'lib/bolt/config.rb', line 35 def trusted_external @trusted_external end |
#warnings ⇒ Object (readonly)
Returns the value of attribute warnings.
40 41 42 |
# File 'lib/bolt/config.rb', line 40 def warnings @warnings end |
Class Method Details
.default ⇒ Object
109 110 111 |
# File 'lib/bolt/config.rb', line 109 def self.default new(Bolt::Boltdir.new('.'), {}) end |
.from_boltdir(boltdir, overrides = {}) ⇒ Object
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/bolt/config.rb', line 113 def self.from_boltdir(boltdir, overrides = {}) data = { filepath: boltdir.config_file, data: Bolt::Util.read_optional_yaml_hash(boltdir.config_file, 'config') } data = load_defaults.push(data).select { |config| config[:data]&.any? } new(boltdir, data, overrides) end |
.from_file(configfile, overrides = {}) ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/bolt/config.rb', line 124 def self.from_file(configfile, overrides = {}) boltdir = Bolt::Boltdir.new(Pathname.new(configfile)..dirname) data = { filepath: boltdir.config_file, data: Bolt::Util.read_yaml_hash(configfile, 'config') } data = load_defaults.push(data).select { |config| config[:data]&.any? } new(boltdir, data, overrides) end |
.load_defaults ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/bolt/config.rb', line 136 def self.load_defaults # Lazy-load expensive gem code require 'win32/dir' if Bolt::Util.windows? system_path = if Bolt::Util.windows? Pathname.new(File.join(Dir::COMMON_APPDATA, 'PuppetLabs', 'bolt', 'etc', 'bolt.yaml')) else Pathname.new(File.join('/etc', 'puppetlabs', 'bolt', 'bolt.yaml')) end user_path = Pathname.new(File.(File.join('~', '.puppetlabs', 'etc', 'bolt', 'bolt.yaml'))) [{ filepath: system_path, data: Bolt::Util.read_optional_yaml_hash(system_path, 'config') }, { filepath: user_path, data: Bolt::Util.read_optional_yaml_hash(user_path, 'config') }] end |
Instance Method Details
#apply_overrides(options) ⇒ Object
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/bolt/config.rb', line 306 def apply_overrides() i[concurrency transport format trace modulepath inventoryfile color].each do |key| send("#{key}=", [key]) if .key?(key) end @save_rerun = [:'save-rerun'] if .key?(:'save-rerun') if [:debug] @log['console'][:level] = :debug end @compile_concurrency = [:'compile-concurrency'] if [:'compile-concurrency'] TRANSPORTS.each_key do |transport| # Get the options first since transport is modified in the next line = TRANSPORTS[transport]::OPTIONS.keys.map(&:to_sym) transport = @transports[transport] .each do |key| if [key] transport[key.to_s] = Bolt::Util.walk_keys([key], &:to_s) end end end if .key?(:ssl) # this defaults to true so we need to check the presence of the key @transports[:winrm]['ssl'] = [:ssl] end if .key?(:'ssl-verify') # this defaults to true so we need to check the presence of the key @transports[:winrm]['ssl-verify'] = [:'ssl-verify'] end if .key?(:'host-key-check') # this defaults to true so we need to check the presence of the key @transports[:ssh]['host-key-check'] = [:'host-key-check'] end end |
#casefold(path) ⇒ Object
449 450 451 452 453 |
# File 'lib/bolt/config.rb', line 449 def casefold(path) path.chars.map do |l| l =~ /[A-Za-z]/ ? "[#{l.upcase}#{l.downcase}]" : l end.join end |
#check_path_case(type, paths) ⇒ Object
Check if there is a case-insensitive match to the path
434 435 436 437 438 439 440 441 442 443 |
# File 'lib/bolt/config.rb', line 434 def check_path_case(type, paths) return if paths.nil? matches = matching_paths(paths) if matches.any? msg = "WARNING: Bolt is case sensitive when specifying a #{type}. Did you mean:\n" matches.each { |path| msg += " #{path}\n" } @logger.warn msg end end |
#deep_clone ⇒ Object
222 223 224 |
# File 'lib/bolt/config.rb', line 222 def deep_clone Bolt::Util.deep_clone(self) end |
#default_inventoryfile ⇒ Object
373 374 375 |
# File 'lib/bolt/config.rb', line 373 def default_inventoryfile @boltdir.inventory_file end |
#hiera_config ⇒ Object
381 382 383 |
# File 'lib/bolt/config.rb', line 381 def hiera_config @hiera_config || @boltdir.hiera_config end |
#matching_paths(paths) ⇒ Object
445 446 447 |
# File 'lib/bolt/config.rb', line 445 def matching_paths(paths) [*paths].map { |p| Dir.glob([p, casefold(p)]) }.flatten.uniq.reject { |p| [*paths].include?(p) } end |
#merge_config_data(config_data) ⇒ Object
Merge configuration Precedence from highest to lowest is: project, user-level, system-wide
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/bolt/config.rb', line 192 def merge_config_data(config_data) config_data.inject({}) do |acc, config| acc.merge(config[:data]) do |key, val1, val2| case key # Plugin config is shallow merged for each plugin when 'plugins' val1.merge(val2) { |_, v1, v2| v1.merge(v2) } # Transports are deep merged when *TRANSPORTS.keys.map(&:to_s) Bolt::Util.deep_merge(val1, val2) # Hash values are shallow mergeed when 'puppetdb', 'plugin_hooks', 'apply_settings', 'log' val1.merge(val2) # All other values are overwritten else val2 end end end end |
#normalize_interpreters(interpreters) ⇒ Object
226 227 228 229 230 |
# File 'lib/bolt/config.rb', line 226 def normalize_interpreters(interpreters) Bolt::Util.walk_keys(interpreters) do |key| key.chars[0] == '.' ? key : '.' + key end end |
#normalize_log(target) ⇒ Object
232 233 234 235 236 |
# File 'lib/bolt/config.rb', line 232 def normalize_log(target) return target if target == 'console' target = target[5..-1] if target.start_with?('file:') 'file:' + File.(target, @boltdir.path) end |
#overwrite_transport_data(transport, transports) ⇒ Object
213 214 215 216 |
# File 'lib/bolt/config.rb', line 213 def overwrite_transport_data(transport, transports) @transport = transport @transports = transports end |
#puppetfile ⇒ Object
385 386 387 |
# File 'lib/bolt/config.rb', line 385 def puppetfile @boltdir.puppetfile end |
#rerunfile ⇒ Object
377 378 379 |
# File 'lib/bolt/config.rb', line 377 def rerunfile @boltdir.rerunfile end |
#transport_conf ⇒ Object
368 369 370 371 |
# File 'lib/bolt/config.rb', line 368 def transport_conf { transport: @transport, transports: @transports } end |
#transport_data_get ⇒ Object
218 219 220 |
# File 'lib/bolt/config.rb', line 218 def transport_data_get { transport: @transport, transports: @transports } end |
#update_from_inventory(data) ⇒ Object
343 344 345 |
# File 'lib/bolt/config.rb', line 343 def update_from_inventory(data) update_transports(data) end |
#update_logs(logs) ⇒ Object
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/bolt/config.rb', line 238 def update_logs(logs) logs.each_pair do |k, v| log_name = normalize_log(k) @log[log_name] ||= {} log = @log[log_name] next unless v.is_a?(Hash) if v.key?('level') log[:level] = v['level'].to_s end if v.key?('append') log[:append] = v['append'] end end end |
#update_transports(data) ⇒ Object
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
# File 'lib/bolt/config.rb', line 347 def update_transports(data) TRANSPORTS.each do |key, impl| if data[key.to_s] selected = impl.(data[key.to_s]) # Expand file paths relative to the Boltdir = %w[private-key cacert token-file] & selected.keys .each do |opt| selected[opt] = File.(selected[opt], @boltdir.path) if selected[opt].is_a?(String) end @transports[key] = Bolt::Util.deep_merge(@transports[key], selected) end if @transports[key]['interpreters'] @transports[key]['interpreters'] = normalize_interpreters(@transports[key]['interpreters']) end end @transport = data['transport'] if data.key?('transport') end |
#validate ⇒ Object
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/bolt/config.rb', line 393 def validate @log.each_pair do |name, params| if params.key?(:level) && !Bolt::Logger.valid_level?(params[:level]) raise Bolt::ValidationError, "level of log #{name} must be one of: #{Bolt::Logger.levels.join(', ')}; received #{params[:level]}" end if params.key?(:append) && params[:append] != true && params[:append] != false raise Bolt::ValidationError, "append flag of log #{name} must be a Boolean, received #{params[:append]}" end end unless @concurrency.is_a?(Integer) && @concurrency > 0 raise Bolt::ValidationError, 'Concurrency must be a positive integer' end unless @compile_concurrency.is_a?(Integer) && @compile_concurrency > 0 raise Bolt::ValidationError, 'Compile concurrency must be a positive integer' end compile_limit = 2 * Etc.nprocessors unless @compile_concurrency < compile_limit raise Bolt::ValidationError, "Compilation is CPU-intensive, set concurrency less than #{compile_limit}" end unless %w[human json].include? @format raise Bolt::ValidationError, "Unsupported format: '#{@format}'" end Bolt::Util.validate_file('hiera-config', @hiera_config) if @hiera_config Bolt::Util.validate_file('trusted-external-command', @trusted_external) if @trusted_external unless @transport.nil? || Bolt::TRANSPORTS.include?(@transport.to_sym) raise UnknownTransportError, @transport end TRANSPORTS.each do |transport, impl| impl.validate(@transports[transport]) end end |