chef-config 18.0.169 → 18.0.172

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,1305 +1,1305 @@
1
- #
2
- # Author:: Adam Jacob (<adam@chef.io>)
3
- # Author:: Christopher Brown (<cb@chef.io>)
4
- # Author:: AJ Christensen (<aj@chef.io>)
5
- # Author:: Mark Mzyk (<mmzyk@chef.io>)
6
- # Author:: Kyle Goodwin (<kgoodwin@primerevenue.com>)
7
- # Copyright:: Copyright (c) Chef Software Inc.
8
- # License:: Apache License, Version 2.0
9
- #
10
- # Licensed under the Apache License, Version 2.0 (the "License");
11
- # you may not use this file except in compliance with the License.
12
- # You may obtain a copy of the License at
13
- #
14
- # http://www.apache.org/licenses/LICENSE-2.0
15
- #
16
- # Unless required by applicable law or agreed to in writing, software
17
- # distributed under the License is distributed on an "AS IS" BASIS,
18
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
- # See the License for the specific language governing permissions and
20
- # limitations under the License.
21
-
22
- require "mixlib/config" unless defined?(Mixlib::Config)
23
- autoload :Pathname, "pathname"
24
- autoload :ChefUtils, "chef-utils"
25
-
26
- require_relative "fips"
27
- require_relative "logger"
28
- require_relative "windows"
29
- require_relative "path_helper"
30
- require_relative "mixin/fuzzy_hostname_matcher"
31
-
32
- module Mixlib
33
- autoload :ShellOut, "mixlib/shellout"
34
- end
35
- autoload :URI, "uri"
36
- module Addressable
37
- autoload :URI, "addressable/uri"
38
- end
39
- autoload :OpenSSL, "openssl"
40
- autoload :YAML, "yaml"
41
- require "chef-utils/dist" unless defined?(ChefUtils::Dist)
42
-
43
- module ChefConfig
44
-
45
- class Config
46
-
47
- extend Mixlib::Config
48
- extend ChefConfig::Mixin::FuzzyHostnameMatcher
49
-
50
- # Evaluates the given string as config.
51
- #
52
- # +filename+ is used for context in stacktraces, but doesn't need to be the name of an actual file.
53
- def self.from_string(string, filename)
54
- instance_eval(string, filename, 1)
55
- end
56
-
57
- def self.inspect
58
- configuration.inspect
59
- end
60
-
61
- # given a *nix style config path return the platform specific path
62
- # to that same config file
63
- # @example client.pem path on Windows
64
- # platform_specific_path("/etc/chef/client.pem") #=> "C:\\chef\\client.pem"
65
- # @param path [String] The unix path to convert to a platform specific path
66
- # @return [String] a platform specific path
67
- def self.platform_specific_path(path)
68
- path = PathHelper.cleanpath(path)
69
- if ChefUtils.windows?
70
- # turns \etc\chef\client.rb and \var\chef\client.rb into C:/chef/client.rb
71
- # Some installations will be on different drives so use the drive that
72
- # the expanded path to __FILE__ is found.
73
- drive = windows_installation_drive
74
- if drive && path[0] == "\\" && path.split("\\")[2] == "chef"
75
- path = PathHelper.join(drive, path.split("\\", 3)[2])
76
- end
77
- end
78
- path
79
- end
80
-
81
- # On *nix, /etc/chef, on Windows C:\chef
82
- #
83
- # @param windows [Boolean] optional flag to force to windows or unix-style
84
- # @return [String] the platform-specific path
85
- #
86
- def self.etc_chef_dir(windows: ChefUtils.windows?)
87
- @etc_chef_dir ||= {}
88
- @etc_chef_dir[windows] ||= begin
89
- path = windows ? c_chef_dir : PathHelper.join("/etc", ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
90
- PathHelper.cleanpath(path, windows: windows)
91
- end
92
- end
93
-
94
- # On *nix, /var/chef, on Windows C:\chef
95
- #
96
- # @param windows [Boolean] optional flag to force to windows or unix-style
97
- # @return [String] the platform-specific path
98
- #
99
- def self.var_chef_dir(windows: ChefUtils.windows?)
100
- path = windows ? c_chef_dir : PathHelper.join("/var", ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
101
- PathHelper.cleanpath(path, windows: windows)
102
- end
103
-
104
- # On *nix, /var, on Windows C:\
105
- #
106
- # @param windows [Boolean] optional flag to force to windows or unix-style
107
- # @return [String] the platform-specific path
108
- #
109
- def self.var_root_dir(windows: ChefUtils.windows?)
110
- path = windows ? "C:\\" : "/var"
111
- PathHelper.cleanpath(path, windows: windows)
112
- end
113
-
114
- # On windows, C:/chef/
115
- #
116
- # (should only be called in a windows-context)
117
- #
118
- # @return [String] the platform-specific path
119
- #
120
- def self.c_chef_dir(windows: ChefUtils.windows?)
121
- drive = windows_installation_drive || "C:"
122
- PathHelper.join(drive, ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
123
- end
124
-
125
- # On windows, C:/opscode
126
- #
127
- # (should only be called in a windows-context)
128
- #
129
- # @return [String] the platform-specific path
130
- #
131
- def self.c_opscode_dir(windows: ChefUtils.windows?)
132
- drive = windows_installation_drive || "C:"
133
- PathHelper.join(drive, ChefUtils::Dist::Org::LEGACY_CONF_DIR, ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
134
- end
135
-
136
- # the drive where Chef is installed on a windows host. This is determined
137
- # either by the drive containing the current file or by the SYSTEMDRIVE ENV
138
- # variable
139
- #
140
- # (should only be called in a windows-context)
141
- #
142
- # @return [String] the drive letter
143
- #
144
- def self.windows_installation_drive
145
- if ChefUtils.windows?
146
- drive = File.expand_path(__FILE__).split("/", 2)[0]
147
- drive = ENV["SYSTEMDRIVE"] if drive.to_s == ""
148
- drive
149
- end
150
- end
151
-
152
- # @param name [String]
153
- # @param file_path [String]
154
- def self.add_formatter(name, file_path = nil)
155
- formatters << [name, file_path]
156
- end
157
-
158
- # @param logger [String]
159
- def self.add_event_logger(logger)
160
- event_handlers << logger
161
- end
162
-
163
- def self.apply_extra_config_options(extra_config_options)
164
- if extra_config_options
165
- extra_parsed_options = extra_config_options.inject({}) do |memo, option|
166
- # Sanity check value.
167
- if option.empty? || !option.include?("=")
168
- raise UnparsableConfigOption, "Unparsable config option #{option.inspect}"
169
- end
170
-
171
- # Split including whitespace if someone does truly odd like
172
- # --config-option "foo = bar"
173
- key, value = option.split(/\s*=\s*/, 2)
174
-
175
- # Call to_sym because Chef::Config expects only symbol keys. Also
176
- # runs a simple parse on the string for some common types.
177
- memo[key.to_sym] = YAML.safe_load(value, permitted_classes: [Date])
178
- memo
179
- end
180
- set_extra_config_options(extra_parsed_options)
181
- end
182
- end
183
-
184
- # We use :[]= assignment here to not bypass any coercions that happen via mixlib-config writes_value callbacks
185
- def self.set_extra_config_options(extra_parsed_options)
186
- extra_parsed_options.each do |key, value|
187
- self[key.to_sym] = value
188
- end
189
- end
190
-
191
- # Config file to load (client.rb, knife.rb, etc. defaults set differently in knife, chef-client, etc.)
192
- configurable(:config_file)
193
-
194
- default(:config_dir) do
195
- if config_file
196
- PathHelper.dirname(PathHelper.canonical_path(config_file, false))
197
- else
198
- PathHelper.join(PathHelper.cleanpath(user_home), ChefUtils::Dist::Infra::USER_CONF_DIR, "")
199
- end
200
- end
201
-
202
- default :formatters, []
203
-
204
- # @param uri [String] the URI to validate
205
- #
206
- # @return [Boolean] is the URL valid
207
- def self.is_valid_url?(uri)
208
- url = uri.to_s.strip
209
- %r{^http://} =~ url || %r{^https://} =~ url || /^chefzero:/ =~ url
210
- end
211
-
212
- # Override the config dispatch to set the value of multiple server options simultaneously
213
- #
214
- # @param [String] url String to be set for all of the chef-server-api URL's
215
- #
216
- configurable(:chef_server_url).writes_value do |uri|
217
- unless is_valid_url? uri
218
- raise ConfigurationError, "#{uri} is an invalid chef_server_url. The URL must start with http://, https://, or chefzero://."
219
- end
220
-
221
- uri.to_s.strip
222
- end
223
-
224
- # When you are using ActiveSupport, they monkey-patch 'daemonize' into Kernel.
225
- # So while this is basically identical to what method_missing would do, we pull
226
- # it up here and get a real method written so that things get dispatched
227
- # properly.
228
- configurable(:daemonize).writes_value { |v| v }
229
-
230
- def self.expand_relative_paths(path)
231
- unless path.nil?
232
- if path.is_a?(String)
233
- File.expand_path(path)
234
- else
235
- Array(path).map { |path| File.expand_path(path) }
236
- end
237
- end
238
- end
239
-
240
- configurable(:cookbook_path).writes_value { |path| expand_relative_paths(path) }
241
-
242
- configurable(:chef_repo_path).writes_value { |path| expand_relative_paths(path) }
243
-
244
- # The root where all local chef object data is stored. cookbooks, data bags,
245
- # environments are all assumed to be in separate directories under this.
246
- # chef-solo uses these directories for input data. knife commands
247
- # that upload or download files (such as knife upload, knife role from file,
248
- # etc.) work.
249
- default :chef_repo_path do
250
- if configuration[:cookbook_path]
251
- if configuration[:cookbook_path].is_a?(String)
252
- File.expand_path("..", configuration[:cookbook_path])
253
- else
254
- configuration[:cookbook_path].map do |path|
255
- File.expand_path("..", path)
256
- end
257
- end
258
- elsif configuration[:cookbook_artifact_path]
259
- File.expand_path("..", configuration[:cookbook_artifact_path])
260
- else
261
- cache_path
262
- end
263
- end
264
-
265
- def self.find_chef_repo_path(cwd)
266
- # In local mode, we auto-discover the repo root by looking for a path with "cookbooks" under it.
267
- # This allows us to run config-free.
268
- path = cwd
269
- until File.directory?(PathHelper.join(path, "cookbooks")) || File.directory?(PathHelper.join(path, "cookbook_artifacts"))
270
- new_path = File.expand_path("..", path)
271
- if new_path == path
272
- ChefConfig.logger.warn("No cookbooks directory found at or above current directory. Assuming #{cwd}.")
273
- return cwd
274
- end
275
- path = new_path
276
- end
277
- ChefConfig.logger.info("Auto-discovered #{ChefUtils::Dist::Infra::SHORT} repository at #{path}")
278
- path
279
- end
280
-
281
- # @param child_path [String]
282
- def self.derive_path_from_chef_repo_path(child_path)
283
- if chef_repo_path.is_a?(String)
284
- PathHelper.join(chef_repo_path, child_path)
285
- else
286
- chef_repo_path.uniq.map { |path| PathHelper.join(path, child_path) }
287
- end
288
- end
289
-
290
- # Location of acls on disk. String or array of strings.
291
- # Defaults to <chef_repo_path>/acls.
292
- default(:acl_path) { derive_path_from_chef_repo_path("acls") }.writes_value { |path| expand_relative_paths(path) }
293
-
294
- # Location of clients on disk. String or array of strings.
295
- # Defaults to <chef_repo_path>/clients.
296
- default(:client_path) { derive_path_from_chef_repo_path("clients") }.writes_value { |path| expand_relative_paths(path) }
297
-
298
- # Location of client keys on disk. String or array of strings.
299
- # Defaults to <chef_repo_path>/client_keys.
300
- default(:client_key_path) { derive_path_from_chef_repo_path("client_keys") }.writes_value { |path| expand_relative_paths(path) }
301
-
302
- # Location of containers on disk. String or array of strings.
303
- # Defaults to <chef_repo_path>/containers.
304
- default(:container_path) { derive_path_from_chef_repo_path("containers") }.writes_value { |path| expand_relative_paths(path) }
305
-
306
- # Location of cookbook_artifacts on disk. String or array of strings.
307
- # Defaults to <chef_repo_path>/cookbook_artifacts.
308
- default(:cookbook_artifact_path) { derive_path_from_chef_repo_path("cookbook_artifacts") }.writes_value { |path| expand_relative_paths(path) }
309
-
310
- # Location of cookbooks on disk. String or array of strings.
311
- # Defaults to <chef_repo_path>/cookbooks. If chef_repo_path
312
- # is not specified, this is set to /var/chef/cookbooks.
313
- default(:cookbook_path) { derive_path_from_chef_repo_path("cookbooks") }
314
-
315
- # Location of data bags on disk. String or array of strings.
316
- # Defaults to <chef_repo_path>/data_bags.
317
- default(:data_bag_path) { derive_path_from_chef_repo_path("data_bags") }.writes_value { |path| expand_relative_paths(path) }
318
-
319
- # Location of environments on disk. String or array of strings.
320
- # Defaults to <chef_repo_path>/environments.
321
- default(:environment_path) { derive_path_from_chef_repo_path("environments") }.writes_value { |path| expand_relative_paths(path) }
322
-
323
- # Location of groups on disk. String or array of strings.
324
- # Defaults to <chef_repo_path>/groups.
325
- default(:group_path) { derive_path_from_chef_repo_path("groups") }.writes_value { |path| expand_relative_paths(path) }
326
-
327
- # Location of nodes on disk. String or array of strings.
328
- # Defaults to <chef_repo_path>/nodes.
329
- default(:node_path) { derive_path_from_chef_repo_path("nodes") }.writes_value { |path| expand_relative_paths(path) }
330
-
331
- # Location of policies on disk. String or array of strings.
332
- # Defaults to <chef_repo_path>/policies.
333
- default(:policy_path) { derive_path_from_chef_repo_path("policies") }.writes_value { |path| expand_relative_paths(path) }
334
-
335
- # Location of policy_groups on disk. String or array of strings.
336
- # Defaults to <chef_repo_path>/policy_groups.
337
- default(:policy_group_path) { derive_path_from_chef_repo_path("policy_groups") }.writes_value { |path| expand_relative_paths(path) }
338
-
339
- # Location of roles on disk. String or array of strings.
340
- # Defaults to <chef_repo_path>/roles.
341
- default(:role_path) { derive_path_from_chef_repo_path("roles") }.writes_value { |path| expand_relative_paths(path) }
342
-
343
- # Location of users on disk. String or array of strings.
344
- # Defaults to <chef_repo_path>/users.
345
- default(:user_path) { derive_path_from_chef_repo_path("users") }.writes_value { |path| expand_relative_paths(path) }
346
-
347
- # DEPRECATED
348
- default :enforce_path_sanity, false
349
-
350
- # Enforce default paths by default for all APIs, not just the default internal shell_out
351
- default :enforce_default_paths, false
352
-
353
- # Formatted Chef Client output is a beta feature, disabled by default:
354
- default :formatter, "null"
355
-
356
- # The number of times the client should retry when registering with the server
357
- default :client_registration_retries, 5
358
-
359
- # An array of paths to search for knife exec scripts if they aren't in the current directory
360
- default :script_path, []
361
-
362
- # The root of all caches (checksums, cache and backup). If local mode is on,
363
- # this is under the user's home directory.
364
- default(:cache_path) do
365
- if local_mode
366
- PathHelper.join(config_dir, "local-mode-cache")
367
- else
368
- primary_cache_root = var_root_dir
369
- primary_cache_path = var_chef_dir
370
- # Use /var/chef as the cache path only if that folder exists and we can read and write
371
- # into it, or /var exists and we can read and write into it (we'll create /var/chef later).
372
- # Otherwise, we'll create .chef under the user's home directory and use that as
373
- # the cache path.
374
- unless path_accessible?(primary_cache_path) || path_accessible?(primary_cache_root)
375
- secondary_cache_path = PathHelper.join(user_home, ChefUtils::Dist::Infra::USER_CONF_DIR)
376
- secondary_cache_path = target_mode? ? PathHelper.join(secondary_cache_path, target_mode.host) : secondary_cache_path
377
- ChefConfig.logger.trace("Unable to access cache at #{primary_cache_path}. Switching cache to #{secondary_cache_path}")
378
- secondary_cache_path
379
- else
380
- target_mode? ? PathHelper.join(primary_cache_path, target_mode.host) : primary_cache_path
381
- end
382
- end
383
- end
384
-
385
- # Returns true only if the path exists and is readable and writeable for the user.
386
- #
387
- # @param path [String]
388
- def self.path_accessible?(path)
389
- File.exist?(path) && File.readable?(path) && File.writable?(path)
390
- end
391
-
392
- # Where cookbook files are stored on the server (by content checksum)
393
- default(:checksum_path) { PathHelper.join(cache_path, "checksums") }
394
-
395
- # Where chef's cache files should be stored
396
- default(:file_cache_path) { PathHelper.join(cache_path, "cache") }.writes_value { |path| expand_relative_paths(path) }
397
-
398
- # Where chef's cache files should be stored, used for bootstrap on unix filesystems
399
- default(:unix_bootstrap_file_cache_path) { PathHelper.join("/var", ChefUtils::Dist::Infra::DIR_SUFFIX, "cache", windows: false) }
400
-
401
- # Where chef's cache files should be stored, used for bootstrap on windows filesystems
402
- default(:windows_bootstrap_file_cache_path) { PathHelper.join("C:", ChefUtils::Dist::Infra::DIR_SUFFIX, "cache", windows: true) }
403
-
404
- # Where backups of chef-managed files should go
405
- default(:file_backup_path) { PathHelper.join(cache_path, "backup") }
406
-
407
- # Where chef's backup files should be stored, used for bootstrap on unix filesystems
408
- default(:unix_bootstrap_file_backup_path) { PathHelper.join("/var", ChefUtils::Dist::Infra::DIR_SUFFIX, "backup", windows: false) }
409
-
410
- # Where chef's backup files should be stored, used for bootstrap on windows filesystems
411
- default(:windows_bootstrap_file_backup_path) { PathHelper.join("C:", ChefUtils::Dist::Infra::DIR_SUFFIX, "backup", windows: true) }
412
-
413
- # The chef-client (or solo) lockfile.
414
- #
415
- # If your `file_cache_path` resides on a NFS (or non-flock()-supporting
416
- # fs), it's recommended to set this to something like
417
- # '/tmp/chef-client-running.pid'
418
- default(:lockfile) { PathHelper.join(file_cache_path, "#{ChefUtils::Dist::Infra::CLIENT}-running.pid") }
419
-
420
- ## Daemonization Settings ##
421
- # What user should Chef run as?
422
- default :user, nil
423
- default :group, nil
424
- default :umask, 0022
425
-
426
- # Valid log_levels are:
427
- # * :trace
428
- # * :debug
429
- # * :info
430
- # * :warn
431
- # * :fatal
432
- # These work as you'd expect. There is also a special `:auto` setting.
433
- # When set to :auto, Chef will auto adjust the log verbosity based on
434
- # context. When a tty is available (usually because the user is running chef
435
- # in a console), the log level is set to :warn, and output formatters are
436
- # used as the primary mode of output. When a tty is not available, the
437
- # logger is the primary mode of output, and the log level is set to :info
438
- default :log_level, :auto
439
-
440
- # Logging location as either an IO stream or string representing log file path
441
- default :log_location, nil
442
-
443
- # Using `force_formatter` causes chef to default to formatter output when STDOUT is not a tty
444
- default :force_formatter, false
445
-
446
- # Using `force_logger` causes chef to default to logger output when STDOUT is a tty
447
- default :force_logger, false
448
-
449
- # When set to true always print the stacktrace even if we haven't done -l debug
450
- default :always_dump_stacktrace, false
451
-
452
- # Using 'stream_execute_output' will have Chef always stream the execute output
453
- default :stream_execute_output, false
454
-
455
- # Using `show_download_progress` will display the overall progress
456
- # of a remote file download
457
- default :show_download_progress, false
458
- # How often to update the progress meter, in percent
459
- default :download_progress_interval, 10
460
-
461
- default :http_retry_count, 5
462
- default :http_retry_delay, 5
463
- # Whether or not to send the Authorization header again on http redirects.
464
- # As per the plan in https://github.com/chef/chef/pull/7006, this will be
465
- # False in Chef 14, True in Chef 15, and will be removed entirely in Chef 16.
466
- default :http_disable_auth_on_redirect, true
467
-
468
- default :interval, nil
469
- default :once, nil
470
- default :json_attribs, nil
471
- # toggle info level log items that can create a lot of output
472
- default :verbose_logging, true
473
- default :node_name, nil
474
- default :diff_disabled, false
475
- default :diff_filesize_threshold, 10000000
476
- default :diff_output_threshold, 1000000
477
-
478
- # This is true for "local mode" which uses a chef-zero server listening on
479
- # localhost one way or another. This is true for both `chef-solo` (without
480
- # the --legacy-mode flag) or `chef-client -z` methods of starting a client run.
481
- #
482
- default :local_mode, false
483
-
484
- # Configures the mode of operation for ChefFS, which is applied to the
485
- # ChefFS-based knife commands and chef-client's local mode. (ChefFS-based
486
- # knife commands include: knife delete, knife deps, knife diff, knife down,
487
- # knife edit, knife list, knife show, knife upload, and knife xargs.)
488
- #
489
- # Valid values are:
490
- # * "static": ChefFS only manages objects that exist in a traditional Chef
491
- # Repo as of Chef 11.
492
- # * "everything": ChefFS manages all object types that existed on the OSS
493
- # Chef 11 server.
494
- # * "hosted_everything": ChefFS manages all object types as of the Chef 12
495
- # Server, including RBAC objects and Policyfile objects (new to Chef 12).
496
- default :repo_mode do
497
- if local_mode && !chef_zero.osc_compat
498
- "hosted_everything"
499
- elsif %r{/+organizations/.+}.match?(chef_server_url)
500
- "hosted_everything"
501
- else
502
- "everything"
503
- end
504
- end
505
-
506
- default :pid_file, nil
507
-
508
- # Whether Chef Zero local mode should bind to a port. All internal requests
509
- # will go through the socketless code path regardless, so the socket is
510
- # only needed if other processes will connect to the local mode server.
511
- default :listen, false
512
-
513
- config_context :chef_zero do
514
- config_strict_mode true
515
- default(:enabled) { ChefConfig::Config.local_mode }
516
- default :host, "localhost"
517
- default :port, 8889.upto(9999) # Will try ports from 8889-9999 until one works
518
-
519
- # When set to a String, Chef Zero disables multitenant support. This is
520
- # what you want when using Chef Zero to serve a single Chef Repo. Setting
521
- # this to `false` enables multi-tenant.
522
- default :single_org, "chef"
523
-
524
- # Whether Chef Zero should operate in a mode analogous to OSS Chef Server
525
- # 11 (true) or Chef Server 12 (false). Chef Zero can still serve
526
- # policyfile objects in Chef 11 mode, as long as `repo_mode` is set to
527
- # "hosted_everything". The primary differences are:
528
- # * Chef 11 mode doesn't support multi-tenant, so there is no
529
- # distinction between global and org-specific objects (since there are
530
- # no orgs).
531
- # * Chef 11 mode doesn't expose RBAC objects
532
- default :osc_compat, false
533
- end
534
-
535
- # RFCxxx Target Mode support, value is the name of a remote device to Chef against
536
- # --target exists as a shortcut to enabling target_mode and setting the host
537
- configurable(:target)
538
-
539
- config_context :target_mode do
540
- config_strict_mode false # we don't want to have to add all train configuration keys here
541
- default :enabled, false
542
- default :protocol, "ssh"
543
- # typical additional keys: host, user, password
544
- end
545
-
546
- def self.target_mode?
547
- target_mode.enabled
548
- end
549
-
550
- default :chef_server_url, "https://localhost:443"
551
-
552
- default(:chef_server_root) do
553
- # if the chef_server_url is a path to an organization, aka
554
- # 'some_url.../organizations/*' then remove the '/organization/*' by default
555
- if %r{/organizations/\S*$}.match?(configuration[:chef_server_url])
556
- configuration[:chef_server_url].split("/")[0..-3].join("/")
557
- elsif configuration[:chef_server_url] # default to whatever chef_server_url is
558
- configuration[:chef_server_url]
559
- else
560
- "https://localhost:443"
561
- end
562
- end
563
-
564
- default :rest_timeout, 300
565
-
566
- # This solo setting is now almost entirely useless. It is set to true if chef-solo was
567
- # invoked that way from the command-line (i.e. from Application::Solo as opposed to
568
- # Application::Client). The more useful information is contained in the :solo_legacy_mode
569
- # vs the :local_mode flags which will be set to true or false depending on how solo was
570
- # invoked and actually change more of the behavior. There might be slight differences in
571
- # the behavior of :local_mode due to the behavioral differences in Application::Solo vs.
572
- # Application::Client and `chef-solo` vs `chef-client -z`, but checking this value and
573
- # switching based on it is almost certainly doing the wrong thing and papering over
574
- # bugs that should be fixed in one or the other class, and will be brittle and destined
575
- # to break in the future (and not necessarily on a major version bump). Checking this value
576
- # is also not sufficient to determine if we are not running against a server since this can
577
- # be unset but :local_mode may be set. It would be accurate to check both :solo and :local_mode
578
- # to determine if we're not running against a server, but the more semantically accurate test
579
- # is going to be combining :solo_legacy_mode and :local_mode.
580
- #
581
- # TL;DR: `if Chef::Config[:solo]` is almost certainly buggy code, you should use:
582
- # `if Chef::Config[:local_mode] || Chef::Config[:solo_legacy_mode]`
583
- #
584
- # @api private
585
- default :solo, false
586
-
587
- # This is true for old chef-solo legacy mode without any chef-zero server (chef-solo --legacy-mode)
588
- default :solo_legacy_mode, false
589
-
590
- default :splay, nil
591
- default :why_run, false
592
- default :color, false
593
- default :client_fork, nil
594
- default :ez, false
595
- default :enable_reporting, true
596
- default :enable_reporting_url_fatals, false
597
-
598
- # Chef only needs ohai to run the hostname plugin for the most basic
599
- # functionality. If the rest of the ohai plugins are not needed (like in
600
- # most of our testing scenarios)
601
- default :minimal_ohai, false
602
-
603
- # When consuming Ohai plugins from cookbook segments, we place those plugins in this directory.
604
- # Subsequent chef client runs will wipe and re-populate the directory to ensure cleanliness
605
- default(:ohai_segment_plugin_path) { PathHelper.join(config_dir, "ohai", "cookbook_plugins") }
606
-
607
- ###
608
- # Policyfile Settings
609
- #
610
- # Policyfile is a feature where a node gets its run list and cookbook
611
- # version set from a single document on the server instead of expanding the
612
- # run list and having the server compute the cookbook version set based on
613
- # environment constraints.
614
- #
615
- # Policyfiles are auto-versioned. The user groups nodes by `policy_name`,
616
- # which generally describes a hosts's functional role, and `policy_group`,
617
- # which generally groups nodes by deployment phase (a.k.a., "environment").
618
- # The Chef Server maps a given set of `policy_name` plus `policy_group` to
619
- # a particular revision of a policy.
620
-
621
- default :policy_name, nil
622
- default :policy_group, nil
623
-
624
- # Policyfiles can have multiple run lists, via the named run list feature.
625
- # Generally this will be set by a CLI option via Chef::Application::Client,
626
- # but it could be set in client.rb if desired.
627
-
628
- default :named_run_list, nil
629
-
630
- # Policyfiles can be used in a native mode (default) or compatibility mode.
631
- # Native mode requires Chef Server 12.1 (it can be enabled via feature flag
632
- # on some prior versions). In native mode, policies and associated
633
- # cookbooks are accessed via feature-specific APIs. In compat mode,
634
- # policies are stored as data bags and cookbooks are stored at the
635
- # cookbooks/ endpoint. Compatibility mode can be dangerous on existing Chef
636
- # Servers; it's recommended to upgrade your Chef Server rather than use
637
- # compatibility mode. Compatibility mode remains available so you can use
638
- # policyfiles with servers that don't yet support the native endpoints.
639
- default :policy_document_native_api, true
640
-
641
- # When policyfiles are used in compatibility mode, `policy_name` and
642
- # `policy_group` are instead specified using a combined configuration
643
- # setting, `deployment_group`. For example, if policy_name should be
644
- # "webserver" and policy_group should be "staging", then `deployment_group`
645
- # should be set to "webserver-staging", which is the name of the data bag
646
- # item that the policy will be stored as. NOTE: this setting only has an
647
- # effect if `policy_document_native_api` is set to `false`.
648
- default :deployment_group, nil
649
-
650
- # When using policyfiles you can optionally set it to read the node.run_list
651
- # from the server and have that override the policyfile run_list or the
652
- # named_run_list set in config. With policyfiles there is no depsolving done
653
- # on the run_list items so every item in the run_list must be in the set of
654
- # cookbooks pushed to the node. This enables flows where the node can change
655
- # its run_list and have it persist or to bootstrap nodes with the -j flag. If
656
- # no run_list is set on the server node object then the configured named_run_list
657
- # or run_list out of the policy is used.
658
- default :policy_persist_run_list, false
659
-
660
- # Set these to enable SSL authentication / mutual-authentication
661
- # with the server
662
-
663
- # Client side SSL cert/key for mutual auth
664
- default :ssl_client_cert, nil
665
- default :ssl_client_key, nil
666
-
667
- # Whether or not to verify the SSL cert for all HTTPS requests. When set to
668
- # :verify_peer (default), all HTTPS requests will be validated regardless of other
669
- # SSL verification settings. When set to :verify_none no HTTPS requests will
670
- # be validated.
671
- default :ssl_verify_mode, :verify_peer
672
-
673
- # Needed to coerce string value to a symbol when loading settings from the
674
- # credentials toml files which doesn't allow ruby symbol values
675
- configurable(:ssl_verify_mode).writes_value do |value|
676
- if value.is_a?(String) && value[0] == ":"
677
- value[1..].to_sym
678
- else
679
- value.to_sym
680
- end
681
- end
682
-
683
- # Whether or not to verify the SSL cert for HTTPS requests to the Chef
684
- # server API. If set to `true`, the server's cert will be validated
685
- # regardless of the :ssl_verify_mode setting. This is set to `true` when
686
- # running in local-mode.
687
- # NOTE: This is a workaround until verify_peer is enabled by default.
688
- default(:verify_api_cert) { ChefConfig::Config.local_mode }
689
-
690
- # Path to the default CA bundle files.
691
- default :ssl_ca_path, nil
692
- default(:ssl_ca_file) do
693
- if ChefUtils.windows? && embedded_dir
694
- cacert_path = File.join(embedded_dir, "ssl/certs/cacert.pem")
695
- cacert_path if File.exist?(cacert_path)
696
- else
697
- nil
698
- end
699
- end
700
-
701
- # A directory that contains additional SSL certificates to trust. Any
702
- # certificates in this directory will be added to whatever CA bundle ruby
703
- # is using. Use this to add self-signed certs for your Chef Server or local
704
- # HTTP file servers.
705
- default(:trusted_certs_dir) { PathHelper.join(config_dir, "trusted_certs") }
706
-
707
- # A directory that contains additional configuration scripts to load for chef-client
708
- default(:client_d_dir) { PathHelper.join(config_dir, "client.d") }
709
-
710
- # A directory that contains additional configuration scripts to load for solo
711
- default(:solo_d_dir) { PathHelper.join(config_dir, "solo.d") }
712
-
713
- # A directory that contains additional configuration scripts to load for
714
- # the workstation config
715
- default(:config_d_dir) { PathHelper.join(config_dir, "config.d") }
716
-
717
- # Where should chef-solo download recipes from?
718
- default :recipe_url, nil
719
-
720
- # Set to true if Chef is to set OpenSSL to run in FIPS mode
721
- default(:fips) do
722
- # CHEF_FIPS is used in testing to override checking for system level
723
- # enablement. There are 3 possible values that this variable may have:
724
- # nil - no override and the system will be checked
725
- # empty - FIPS is NOT enabled
726
- # a non empty value - FIPS is enabled
727
- if ENV["CHEF_FIPS"] == ""
728
- false
729
- else
730
- !ENV["CHEF_FIPS"].nil? || ChefConfig.fips?
731
- end
732
- end
733
-
734
- # Initialize openssl
735
- def self.init_openssl
736
- if fips
737
- enable_fips_mode
738
- end
739
- end
740
-
741
- # Sets the version of the signed header authentication protocol to use (see
742
- # the 'mixlib-authorization' project for more detail). Currently, versions
743
- # 1.0, 1.1, and 1.3 are available.
744
- default :authentication_protocol_version do
745
- if fips || ssh_agent_signing
746
- "1.3"
747
- else
748
- "1.1"
749
- end
750
- end
751
-
752
- # This key will be used to sign requests to the Chef server. This location
753
- # must be writable by Chef during initial setup when generating a client
754
- # identity on the server.
755
- #
756
- # The chef-server will look up the public key for the client using the
757
- # `node_name` of the client.
758
- #
759
- # If chef-zero is enabled, this defaults to nil (no authentication).
760
- default(:client_key) do
761
- if chef_zero.enabled
762
- nil
763
- elsif target_mode?
764
- PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/client.pem")
765
- else
766
- PathHelper.cleanpath("#{etc_chef_dir}/client.pem")
767
- end
768
- end
769
-
770
- # A credentials file may contain a complete client key, rather than the path
771
- # to one.
772
- #
773
- # We'll use this preferentially.
774
- default :client_key_contents, nil
775
-
776
- # We want to get all certificates OFF disk and into secure storage. This flag
777
- # removes the client.pem from disk and a replacement is put into Keychain or the Certstore
778
- # Then the public key from the new cert is pushed to Chef Server for authentication
779
- default :migrate_key_to_keystore, false
780
-
781
- # When registering the client, should we allow the client key location to
782
- # be a symlink? eg: /etc/chef/client.pem -> /etc/chef/prod-client.pem
783
- # If the path of the key goes through a directory like /tmp this should
784
- # never be set to true or its possibly an easily exploitable security hole.
785
- default :follow_client_key_symlink, false
786
-
787
- # Enable ssh-agent signing mode. This requires {client_key} be set to a
788
- # public key rather than the usual private key.
789
- default :ssh_agent_signing, false
790
-
791
- # This secret is used to decrypt encrypted data bag items.
792
- default(:encrypted_data_bag_secret) do
793
- if target_mode? && File.exist?(PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/encrypted_data_bag_secret"))
794
- PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/encrypted_data_bag_secret")
795
- elsif File.exist?(PathHelper.cleanpath("#{etc_chef_dir}/encrypted_data_bag_secret"))
796
- PathHelper.cleanpath("#{etc_chef_dir}/encrypted_data_bag_secret")
797
- else
798
- nil
799
- end
800
- end
801
-
802
- # As of Chef 13.0, version "3" is the default encrypted data bag item
803
- # format.
804
- #
805
- default :data_bag_encrypt_version, 3
806
-
807
- # When reading data bag items, any supported version is accepted. However,
808
- # if all encrypted data bags have been generated with the version 2 format,
809
- # it is recommended to disable support for earlier formats to improve
810
- # security. For example, the version 2 format is identical to version 1
811
- # except for the addition of an HMAC, so an attacker with MITM capability
812
- # could downgrade an encrypted data bag to version 1 as part of an attack.
813
- default :data_bag_decrypt_minimum_version, 0
814
-
815
- # If there is no file in the location given by `client_key`, chef-client
816
- # will temporarily use the "validator" identity to generate one. If the
817
- # `client_key` is not present and the `validation_key` is also not present,
818
- # chef-client will not be able to authenticate to the server.
819
- #
820
- # The `validation_key` is never used if the `client_key` exists.
821
- #
822
- # If chef-zero is enabled, this defaults to nil (no authentication).
823
- default(:validation_key) { chef_zero.enabled ? nil : PathHelper.cleanpath("#{etc_chef_dir}/validation.pem") }
824
- default :validation_client_name do
825
- # If the URL is set and looks like a normal Chef Server URL, extract the
826
- # org name and use that as part of the default.
827
- if chef_server_url.to_s =~ %r{/organizations/(.*)$}
828
- "#{$1}-validator"
829
- else
830
- "#{ChefUtils::Dist::Infra::SHORT}-validator"
831
- end
832
- end
833
-
834
- default :validation_key_contents, nil
835
- # When creating a new client via the validation_client account, Chef 11
836
- # servers allow the client to generate a key pair locally and send the
837
- # public key to the server. This is more secure and helps offload work from
838
- # the server, enhancing scalability. If enabled and the remote server
839
- # implements only the Chef 10 API, client registration will not work
840
- # properly.
841
- #
842
- # The default value is `true`. Set to `false` to disable client-side key
843
- # generation (server generates client keys).
844
- default(:local_key_generation) { true }
845
-
846
- # Zypper package provider gpg checks. Set to false to disable package
847
- # gpg signature checking globally. This will warn you that it is a
848
- # bad thing to do.
849
- default :zypper_check_gpg, true
850
-
851
- # Report Handlers
852
- default :report_handlers, []
853
-
854
- # Event Handlers
855
- default :event_handlers, []
856
-
857
- default :disable_event_loggers, false
858
-
859
- # Exception Handlers
860
- default :exception_handlers, []
861
-
862
- # Start handlers
863
- default :start_handlers, []
864
-
865
- # Syntax Check Cache. Knife keeps track of files that is has already syntax
866
- # checked by storing files in this directory. `syntax_check_cache_path` is
867
- # the new (and preferred) configuration setting. If not set, knife will
868
- # fall back to using cache_options[:path], which is deprecated but exists in
869
- # many client configs generated by pre-Chef-11 bootstrappers.
870
- default(:syntax_check_cache_path) { cache_options[:path] }.writes_value { |path| expand_relative_paths(path) }
871
-
872
- # Deprecated:
873
- # Move this to the default value of syntax_cache_path when this is removed.
874
- default(:cache_options) { { path: PathHelper.join(config_dir, "syntaxcache") } }
875
-
876
- # Whether errors should be raised for deprecation warnings. When set to
877
- # `false` (the default setting), a warning is emitted but code using
878
- # deprecated methods/features/etc. should work normally otherwise. When set
879
- # to `true`, usage of deprecated methods/features will raise a
880
- # `DeprecatedFeatureError`. This is used by Chef's tests to ensure that
881
- # deprecated functionality is not used internally by Chef. End users
882
- # should generally leave this at the default setting (especially in
883
- # production), but it may be useful when testing cookbooks or other code if
884
- # the user wishes to aggressively address deprecations.
885
- default(:treat_deprecation_warnings_as_errors) do
886
- # Using an environment variable allows this setting to be inherited in
887
- # tests that spawn new processes.
888
- ENV.key?("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
889
- end
890
-
891
- # Which deprecations warnings to silence. Can be set to `true` to silence
892
- # all warnings, or an array of strings like either `"deprecation_type"` or
893
- # `"filename.rb:lineno"`.
894
- default :silence_deprecation_warnings, []
895
-
896
- # Whether the resource count should be updated for log resource
897
- # on running chef-client
898
- default :count_log_resource_updates, false
899
-
900
- # The selected profile when using credentials.
901
- default :profile, nil
902
-
903
- default :chef_guid_path do
904
- PathHelper.join(config_dir, "#{ChefUtils::Dist::Infra::SHORT}_guid")
905
- end
906
-
907
- default :chef_guid, nil
908
-
909
- # knife configuration data
910
- config_context :knife do
911
- default :hints, {}
912
- end
913
-
914
- def self.set_defaults_for_windows
915
- # Those lists of regular expressions define what chef considers a
916
- # valid user and group name
917
- # From http://technet.microsoft.com/en-us/library/cc776019(WS.10).aspx
918
- principal_valid_regex_part = '[^"\/\\\\\[\]\:;|=,+*?<>]+'
919
- default :user_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
920
- default :group_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
921
-
922
- default :fatal_windows_admin_check, false
923
- end
924
-
925
- def self.set_defaults_for_nix
926
- # Those lists of regular expressions define what chef considers a
927
- # valid user and group name
928
- #
929
- # user/group cannot start with '-', '+' or '~'
930
- # user/group cannot contain ':', ',' or non-space-whitespace or null byte
931
- # everything else is allowed (UTF-8, spaces, etc) and we delegate to your O/S useradd program to barf or not
932
- # copies: http://anonscm.debian.org/viewvc/pkg-shadow/debian/trunk/debian/patches/506_relaxed_usernames?view=markup
933
- default :user_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
934
- default :group_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
935
- end
936
-
937
- # Those lists of regular expressions define what chef considers a
938
- # valid user and group name
939
- if ChefUtils.windows?
940
- set_defaults_for_windows
941
- else
942
- set_defaults_for_nix
943
- end
944
-
945
- # This provides a hook which rspec can stub so that we can avoid twiddling
946
- # global state in tests.
947
- def self.env
948
- ENV
949
- end
950
-
951
- def self.windows_home_path
952
- ChefConfig.logger.deprecation("Chef::Config.windows_home_path is now deprecated. Consider using Chef::Util::PathHelper.home instead.")
953
- PathHelper.home
954
- end
955
-
956
- # returns a platform specific path to the user home dir if set, otherwise default to current directory.
957
- default( :user_home ) { PathHelper.home || Dir.pwd }
958
-
959
- # Enable file permission fixup for selinux. Fixup will be done
960
- # only if selinux is enabled in the system.
961
- default :enable_selinux_file_permission_fixup, true
962
-
963
- # Use atomic updates (i.e. move operation) while updating contents
964
- # of the files resources. When set to false copy operation is
965
- # used to update files.
966
- #
967
- # NOTE: CHANGING THIS SETTING MAY CAUSE CORRUPTION, DATA LOSS AND
968
- # INSTABILITY.
969
- #
970
- default :file_atomic_update, true
971
-
972
- # There are 3 possible values for this configuration setting.
973
- # true => file staging is done in the destination directory
974
- # false => file staging is done via tempfiles under ENV['TMP']
975
- # :auto => file staging will try using destination directory if possible and
976
- # will fall back to ENV['TMP'] if destination directory is not usable.
977
- #
978
- default :file_staging_uses_destdir, :auto
979
-
980
- # Exit if another run is in progress and the chef-client is unable to
981
- # get the lock before time expires. If nil, no timeout is enforced. (Exits
982
- # immediately if 0.)
983
- #
984
- default :run_lock_timeout, nil
985
-
986
- # Number of worker threads for syncing cookbooks in parallel. Increasing
987
- # this number can result in gateway errors from the server (namely 503 and 504).
988
- # If you are seeing this behavior while using the default setting, reducing
989
- # the number of threads will help.
990
- #
991
- default :cookbook_sync_threads, 10
992
-
993
- # True if all resources by default default to unified mode, with all resources
994
- # applying in "compile" mode, with no "converge" mode. False is backwards compatible
995
- # setting for Chef 11-15 behavior. This will break forward notifications.
996
- #
997
- default :resource_unified_mode_default, true
998
-
999
- # At the beginning of the Chef Client run, the cookbook manifests are downloaded which
1000
- # contain URLs for every file in every relevant cookbook. Most of the files
1001
- # (recipes, resources, providers, libraries, etc) are immediately synchronized
1002
- # at the start of the run. The handling of "files" and "templates" directories,
1003
- # however, have two modes of operation. They can either all be downloaded immediately
1004
- # at the start of the run (no_lazy_load==true) or else they can be lazily loaded as
1005
- # cookbook_file or template resources are converged which require them (no_lazy_load==false).
1006
- #
1007
- # The advantage of lazily loading these files is that unnecessary files are not
1008
- # synchronized. This may be useful to users with large files checked into cookbooks which
1009
- # are only selectively downloaded to a subset of clients which use the cookbook. However,
1010
- # better solutions are to either isolate large files into individual cookbooks and only
1011
- # include those cookbooks in the run lists of the servers that need them -- or move to
1012
- # using remote_file and a more appropriate backing store like S3 for large file
1013
- # distribution.
1014
- #
1015
- # The disadvantages of lazily loading files are that users some time find it
1016
- # confusing that their cookbooks are not fully synchronized to the cache initially,
1017
- # and more importantly the time-sensitive URLs which are in the manifest may time
1018
- # out on long Chef runs before the resource that uses the file is converged
1019
- # (leading to many confusing 403 errors on template/cookbook_file resources).
1020
- #
1021
- default :no_lazy_load, true
1022
-
1023
- # A array of attributes you want sent over the wire when node
1024
- # data is saved. The default setting is nil, which collects all data.
1025
- # NOTE: Setting to [] will not collect ANY data to save.
1026
- default :allowed_automatic_attributes, nil
1027
- default :allowed_default_attributes, nil
1028
- default :allowed_normal_attributes, nil
1029
- default :allowed_override_attributes, nil
1030
-
1031
- # An array of attributes you do not want to send over the
1032
- # wire when node data is saved
1033
- # The default setting is nil, which collects all data.
1034
- # NOTE: Setting to [] will still collect all data to save
1035
- default :blocked_automatic_attributes, nil
1036
- default :blocked_default_attributes, nil
1037
- default :blocked_normal_attributes, nil
1038
- default :blocked_override_attributes, nil
1039
-
1040
- # deprecated config options that will be removed in Chef Infra Client 18
1041
- default :automatic_attribute_blacklist, nil
1042
- default :default_attribute_blacklist, nil
1043
- default :normal_attribute_blacklist, nil
1044
- default :override_attribute_blacklist, nil
1045
- default :automatic_attribute_whitelist, nil
1046
- default :default_attribute_whitelist, nil
1047
- default :normal_attribute_whitelist, nil
1048
- default :override_attribute_whitelist, nil
1049
-
1050
- # Pull down all the rubygems versions from rubygems and cache them the first time we do a gem_package or
1051
- # chef_gem install. This is memory-expensive and will grow without bounds, but will reduce network
1052
- # round trips.
1053
- default :rubygems_cache_enabled, false
1054
-
1055
- config_context :windows_service do
1056
- # Set `watchdog_timeout` to the number of seconds to wait for a chef-client run
1057
- # to finish
1058
- default :watchdog_timeout, 2 * (60 * 60) # 2 hours
1059
- end
1060
-
1061
- # Add an empty and non-strict config_context for chefdk and chefcli.
1062
- # This lets the user have code like `chefdk.generator_cookbook "/path/to/cookbook"` or
1063
- # `chefcli[:generator_cookbook] = "/path/to/cookbook"` in their config.rb,
1064
- # and it will be ignored by tools like knife and ohai. ChefDK and ChefCLI
1065
- # themselves can define the config options it accepts and enable strict mode,
1066
- # and that will only apply when running `chef` commands.
1067
- config_context :chefdk do
1068
- end
1069
-
1070
- config_context :chefcli do
1071
- end
1072
-
1073
- # Configuration options for Data Collector reporting. These settings allow
1074
- # the user to configure where to send their Data Collector data, what token
1075
- # to send, and whether Data Collector should report its findings in client
1076
- # mode vs. solo mode.
1077
- config_context :data_collector do
1078
- # Full URL to the endpoint that will receive our data. If nil, the
1079
- # data collector will not run.
1080
- # Ex: http://my-data-collector.mycompany.com/ingest
1081
- default(:server_url) do
1082
- if config_parent.solo_legacy_mode || config_parent.local_mode
1083
- nil
1084
- else
1085
- File.join(config_parent.chef_server_url, "/data-collector")
1086
- end
1087
- end
1088
-
1089
- # An optional pre-shared token to pass as an HTTP header (x-data-collector-token)
1090
- # that can be used to determine whether or not the poster of this
1091
- # run data should be trusted.
1092
- # Ex: some-uuid-here
1093
- default :token, nil
1094
-
1095
- # The Chef mode during which Data Collector is allowed to function. This
1096
- # can be used to run Data Collector only when running as Chef Solo but
1097
- # not when using Chef Client.
1098
- # Options: :solo (for both Solo Legacy Mode and Client Local Mode), :client, :both
1099
- default :mode, :both
1100
-
1101
- # When the Data Collector cannot send the "starting a run" message to
1102
- # the Data Collector server, the Data Collector will be disabled for that
1103
- # run. In some situations, such as highly-regulated environments, it
1104
- # may be more reasonable to prevent Chef from performing the actual run.
1105
- # In these situations, setting this value to true will cause the Chef
1106
- # run to raise an exception before starting any converge activities.
1107
- default :raise_on_failure, false
1108
-
1109
- # A user-supplied Organization string that can be sent in payloads
1110
- # generated by the DataCollector when Chef is run in Solo mode. This
1111
- # allows users to associate their Solo nodes with faux organizations
1112
- # without the nodes being connected to an actual Chef Server.
1113
- default :organization, "#{ChefUtils::Dist::Infra::SHORT}_solo"
1114
- end
1115
-
1116
- configurable(:http_proxy)
1117
- configurable(:http_proxy_user)
1118
- configurable(:http_proxy_pass)
1119
- configurable(:https_proxy)
1120
- configurable(:https_proxy_user)
1121
- configurable(:https_proxy_pass)
1122
- configurable(:ftp_proxy)
1123
- configurable(:ftp_proxy_user)
1124
- configurable(:ftp_proxy_pass)
1125
- configurable(:no_proxy)
1126
-
1127
- # Public method that users should call to export proxies to the appropriate
1128
- # environment variables. This method should be called after the config file is
1129
- # parsed and loaded.
1130
- # TODO add some post-file-parsing logic that automatically calls this so
1131
- # users don't have to
1132
- def self.export_proxies
1133
- export_proxy("http", http_proxy, http_proxy_user, http_proxy_pass) if key?(:http_proxy) && http_proxy
1134
- export_proxy("https", https_proxy, https_proxy_user, https_proxy_pass) if key?(:https_proxy) && https_proxy
1135
- export_proxy("ftp", ftp_proxy, ftp_proxy_user, ftp_proxy_pass) if key?(:ftp_proxy) && ftp_proxy
1136
- export_no_proxy(no_proxy) if key?(:no_proxy) && no_proxy
1137
- end
1138
-
1139
- # Builds a proxy uri and exports it to the appropriate environment variables. Examples:
1140
- # http://username:password@hostname:port
1141
- # https://username@hostname:port
1142
- # ftp://hostname:port
1143
- # when
1144
- # scheme = "http", "https", or "ftp"
1145
- # hostport = hostname:port or scheme://hostname:port
1146
- # user = username
1147
- # pass = password
1148
- # @api private
1149
- def self.export_proxy(scheme, path, user, pass)
1150
- # Character classes for Addressable
1151
- # See https://www.ietf.org/rfc/rfc3986.txt 3.2.1
1152
- # The user part may not have a : in it
1153
- user_class = Addressable::URI::CharacterClasses::UNRESERVED + Addressable::URI::CharacterClasses::SUB_DELIMS
1154
- # The password part may have any valid USERINFO characters
1155
- password_class = user_class + "\\:"
1156
-
1157
- path = "#{scheme}://#{path}" unless path.include?("://")
1158
- # URI.split returns the following parts:
1159
- # [scheme, userinfo, host, port, registry, path, opaque, query, fragment]
1160
- uri = Addressable::URI.encode(path, Addressable::URI)
1161
-
1162
- if user && !user.empty?
1163
- userinfo = Addressable::URI.encode_component(user, user_class)
1164
- if pass
1165
- userinfo << ":#{Addressable::URI.encode_component(pass, password_class)}"
1166
- end
1167
- uri.userinfo = userinfo
1168
- end
1169
-
1170
- path = uri.to_s
1171
- ENV["#{scheme}_proxy".downcase] = path unless ENV["#{scheme}_proxy".downcase]
1172
- ENV["#{scheme}_proxy".upcase] = path unless ENV["#{scheme}_proxy".upcase]
1173
- end
1174
-
1175
- # @api private
1176
- def self.export_no_proxy(value)
1177
- ENV["no_proxy"] = value unless ENV["no_proxy"]
1178
- ENV["NO_PROXY"] = value unless ENV["NO_PROXY"]
1179
- end
1180
-
1181
- # Given a scheme, host, and port, return the correct proxy URI based on the
1182
- # set environment variables, unless excluded by no_proxy, in which case nil
1183
- # is returned
1184
- def self.proxy_uri(scheme, host, port)
1185
- proxy_env_var = ENV["#{scheme}_proxy"].to_s.strip
1186
-
1187
- # Check if the proxy string contains a scheme. If not, add the url's scheme to the
1188
- # proxy before parsing. The regex /^.*:\/\// matches, for example, http://. Reusing proxy
1189
- # here since we are really just trying to get the string built correctly.
1190
- proxy = unless proxy_env_var.empty?
1191
- if %r{^.*://}.match?(proxy_env_var)
1192
- URI.parse(proxy_env_var)
1193
- else
1194
- URI.parse("#{scheme}://#{proxy_env_var}")
1195
- end
1196
- end
1197
-
1198
- return proxy unless fuzzy_hostname_match_any?(host, ENV["no_proxy"])
1199
- end
1200
-
1201
- # Chef requires an English-language UTF-8 locale to function properly. We attempt
1202
- # to use the 'locale -a' command and search through a list of preferences until we
1203
- # find one that we can use. On Ubuntu systems we should find 'C.UTF-8' and be
1204
- # able to use that even if there is no English locale on the server, but Mac, Solaris,
1205
- # AIX, etc do not have that locale. We then try to find an English locale and fall
1206
- # back to 'C' if we do not. The choice of fallback is pick-your-poison. If we try
1207
- # to do the work to return a non-US UTF-8 locale then we fail inside of providers when
1208
- # things like 'svn info' return Japanese and we can't parse them. OTOH, if we pick 'C' then
1209
- # we will blow up on UTF-8 characters. Between the warn we throw and the Encoding
1210
- # exception that ruby will throw it is more obvious what is broken if we drop UTF-8 by
1211
- # default rather than drop English.
1212
- #
1213
- # If there is no 'locale -a' then we return 'en_US.UTF-8' since that is the most commonly
1214
- # available English UTF-8 locale. However, all modern POSIXen should support 'locale -a'.
1215
- def self.guess_internal_locale
1216
- # https://github.com/chef/chef/issues/2181
1217
- # Some systems have the `locale -a` command, but the result has
1218
- # invalid characters for the default encoding.
1219
- #
1220
- # For example, on CentOS 6 with ENV['LANG'] = "en_US.UTF-8",
1221
- # `locale -a`.split fails with ArgumentError invalid UTF-8 encoding.
1222
- cmd = Mixlib::ShellOut.new("locale -a").run_command
1223
- cmd.error!
1224
- locales = cmd.stdout.split
1225
- case
1226
- when locales.include?("C.UTF-8")
1227
- "C.UTF-8"
1228
- when locales.include?("en_US.UTF-8"), locales.include?("en_US.utf8")
1229
- "en_US.UTF-8"
1230
- when locales.include?("en.UTF-8")
1231
- "en.UTF-8"
1232
- else
1233
- # Will match en_ZZ.UTF-8, en_ZZ.utf-8, en_ZZ.UTF8, en_ZZ.utf8
1234
- guesses = locales.grep(/^en_.*UTF-?8$/i)
1235
- unless guesses.empty?
1236
- guessed_locale = guesses.first
1237
- # Transform into the form en_ZZ.UTF-8
1238
- guessed_locale.gsub(/UTF-?8$/i, "UTF-8")
1239
- else
1240
- ChefConfig.logger.warn "Please install an English UTF-8 locale for #{ChefUtils::Dist::Infra::PRODUCT} to use, falling back to C locale and disabling UTF-8 support."
1241
- "C"
1242
- end
1243
- end
1244
- rescue
1245
- if ChefUtils.windows?
1246
- ChefConfig.logger.trace "Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else."
1247
- else
1248
- ChefConfig.logger.trace "No usable locale -a command found, assuming you have en_US.UTF-8 installed."
1249
- end
1250
- "en_US.UTF-8"
1251
- end
1252
-
1253
- default :internal_locale, guess_internal_locale
1254
-
1255
- # Force UTF-8 Encoding, for when we fire up in the 'C' locale or other strange locales (e.g.
1256
- # japanese windows encodings). If we do not do this, then knife upload will fail when a cookbook's
1257
- # README.md has UTF-8 characters that do not encode in whatever surrounding encoding we have been
1258
- # passed. Effectively, the Chef Ecosystem is globally UTF-8 by default. Anyone who wants to be
1259
- # able to upload Shift_JIS or ISO-8859-1 files needs to mark *those* files explicitly with
1260
- # magic tags to make ruby correctly identify the encoding being used. Changing this default will
1261
- # break Chef community cookbooks and is very highly discouraged.
1262
- default :ruby_encoding, Encoding::UTF_8
1263
-
1264
- # can be set to a string or array of strings for URIs to set as rubygems sources
1265
- default :rubygems_url, nil
1266
-
1267
- # globally sets the default of the clear_sources property on the gem_package and chef_gem resources
1268
- default :clear_gem_sources, nil
1269
-
1270
- # If installed via an omnibus installer, this gives the path to the
1271
- # "embedded" directory which contains all of the software packaged with
1272
- # omnibus. This is used to locate the cacert.pem file on windows.
1273
- def self.embedded_dir
1274
- Pathname.new(_this_file).ascend do |path|
1275
- if path.basename.to_s == "embedded"
1276
- return path.to_s
1277
- end
1278
- end
1279
-
1280
- nil
1281
- end
1282
-
1283
- # Path to this file in the current install.
1284
- def self._this_file
1285
- File.expand_path(__FILE__)
1286
- end
1287
-
1288
- # Set fips mode in openssl. Do any patching necessary to make
1289
- # sure Chef runs do not crash.
1290
- # @api private
1291
- def self.enable_fips_mode
1292
- OpenSSL.fips_mode = true
1293
- require "digest" unless defined?(Digest)
1294
- require "digest/sha1" unless defined?(Digest::SHA1)
1295
- require "digest/md5" unless defined?(Digest::MD5)
1296
- # Remove pre-existing constants if they do exist to reduce the
1297
- # amount of log spam and warnings.
1298
- Digest.send(:remove_const, "SHA1") if Digest.const_defined?(:SHA1)
1299
- Digest.const_set(:SHA1, OpenSSL::Digest::SHA1)
1300
- OpenSSL::Digest.send(:remove_const, "MD5") if OpenSSL::Digest.const_defined?(:MD5)
1301
- OpenSSL::Digest.const_set(:MD5, Digest::MD5)
1302
- ChefConfig.logger.debug "FIPS mode is enabled."
1303
- end
1304
- end
1305
- end
1
+ #
2
+ # Author:: Adam Jacob (<adam@chef.io>)
3
+ # Author:: Christopher Brown (<cb@chef.io>)
4
+ # Author:: AJ Christensen (<aj@chef.io>)
5
+ # Author:: Mark Mzyk (<mmzyk@chef.io>)
6
+ # Author:: Kyle Goodwin (<kgoodwin@primerevenue.com>)
7
+ # Copyright:: Copyright (c) Chef Software Inc.
8
+ # License:: Apache License, Version 2.0
9
+ #
10
+ # Licensed under the Apache License, Version 2.0 (the "License");
11
+ # you may not use this file except in compliance with the License.
12
+ # You may obtain a copy of the License at
13
+ #
14
+ # http://www.apache.org/licenses/LICENSE-2.0
15
+ #
16
+ # Unless required by applicable law or agreed to in writing, software
17
+ # distributed under the License is distributed on an "AS IS" BASIS,
18
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
+ # See the License for the specific language governing permissions and
20
+ # limitations under the License.
21
+
22
+ require "mixlib/config" unless defined?(Mixlib::Config)
23
+ autoload :Pathname, "pathname"
24
+ autoload :ChefUtils, "chef-utils"
25
+
26
+ require_relative "fips"
27
+ require_relative "logger"
28
+ require_relative "windows"
29
+ require_relative "path_helper"
30
+ require_relative "mixin/fuzzy_hostname_matcher"
31
+
32
+ module Mixlib
33
+ autoload :ShellOut, "mixlib/shellout"
34
+ end
35
+ autoload :URI, "uri"
36
+ module Addressable
37
+ autoload :URI, "addressable/uri"
38
+ end
39
+ autoload :OpenSSL, "openssl"
40
+ autoload :YAML, "yaml"
41
+ require "chef-utils/dist" unless defined?(ChefUtils::Dist)
42
+
43
+ module ChefConfig
44
+
45
+ class Config
46
+
47
+ extend Mixlib::Config
48
+ extend ChefConfig::Mixin::FuzzyHostnameMatcher
49
+
50
+ # Evaluates the given string as config.
51
+ #
52
+ # +filename+ is used for context in stacktraces, but doesn't need to be the name of an actual file.
53
+ def self.from_string(string, filename)
54
+ instance_eval(string, filename, 1)
55
+ end
56
+
57
+ def self.inspect
58
+ configuration.inspect
59
+ end
60
+
61
+ # given a *nix style config path return the platform specific path
62
+ # to that same config file
63
+ # @example client.pem path on Windows
64
+ # platform_specific_path("/etc/chef/client.pem") #=> "C:\\chef\\client.pem"
65
+ # @param path [String] The unix path to convert to a platform specific path
66
+ # @return [String] a platform specific path
67
+ def self.platform_specific_path(path)
68
+ path = PathHelper.cleanpath(path)
69
+ if ChefUtils.windows?
70
+ # turns \etc\chef\client.rb and \var\chef\client.rb into C:/chef/client.rb
71
+ # Some installations will be on different drives so use the drive that
72
+ # the expanded path to __FILE__ is found.
73
+ drive = windows_installation_drive
74
+ if drive && path[0] == "\\" && path.split("\\")[2] == "chef"
75
+ path = PathHelper.join(drive, path.split("\\", 3)[2])
76
+ end
77
+ end
78
+ path
79
+ end
80
+
81
+ # On *nix, /etc/chef, on Windows C:\chef
82
+ #
83
+ # @param windows [Boolean] optional flag to force to windows or unix-style
84
+ # @return [String] the platform-specific path
85
+ #
86
+ def self.etc_chef_dir(windows: ChefUtils.windows?)
87
+ @etc_chef_dir ||= {}
88
+ @etc_chef_dir[windows] ||= begin
89
+ path = windows ? c_chef_dir : PathHelper.join("/etc", ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
90
+ PathHelper.cleanpath(path, windows: windows)
91
+ end
92
+ end
93
+
94
+ # On *nix, /var/chef, on Windows C:\chef
95
+ #
96
+ # @param windows [Boolean] optional flag to force to windows or unix-style
97
+ # @return [String] the platform-specific path
98
+ #
99
+ def self.var_chef_dir(windows: ChefUtils.windows?)
100
+ path = windows ? c_chef_dir : PathHelper.join("/var", ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
101
+ PathHelper.cleanpath(path, windows: windows)
102
+ end
103
+
104
+ # On *nix, /var, on Windows C:\
105
+ #
106
+ # @param windows [Boolean] optional flag to force to windows or unix-style
107
+ # @return [String] the platform-specific path
108
+ #
109
+ def self.var_root_dir(windows: ChefUtils.windows?)
110
+ path = windows ? "C:\\" : "/var"
111
+ PathHelper.cleanpath(path, windows: windows)
112
+ end
113
+
114
+ # On windows, C:/chef/
115
+ #
116
+ # (should only be called in a windows-context)
117
+ #
118
+ # @return [String] the platform-specific path
119
+ #
120
+ def self.c_chef_dir(windows: ChefUtils.windows?)
121
+ drive = windows_installation_drive || "C:"
122
+ PathHelper.join(drive, ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
123
+ end
124
+
125
+ # On windows, C:/opscode
126
+ #
127
+ # (should only be called in a windows-context)
128
+ #
129
+ # @return [String] the platform-specific path
130
+ #
131
+ def self.c_opscode_dir(windows: ChefUtils.windows?)
132
+ drive = windows_installation_drive || "C:"
133
+ PathHelper.join(drive, ChefUtils::Dist::Org::LEGACY_CONF_DIR, ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
134
+ end
135
+
136
+ # the drive where Chef is installed on a windows host. This is determined
137
+ # either by the drive containing the current file or by the SYSTEMDRIVE ENV
138
+ # variable
139
+ #
140
+ # (should only be called in a windows-context)
141
+ #
142
+ # @return [String] the drive letter
143
+ #
144
+ def self.windows_installation_drive
145
+ if ChefUtils.windows?
146
+ drive = File.expand_path(__FILE__).split("/", 2)[0]
147
+ drive = ENV["SYSTEMDRIVE"] if drive.to_s == ""
148
+ drive
149
+ end
150
+ end
151
+
152
+ # @param name [String]
153
+ # @param file_path [String]
154
+ def self.add_formatter(name, file_path = nil)
155
+ formatters << [name, file_path]
156
+ end
157
+
158
+ # @param logger [String]
159
+ def self.add_event_logger(logger)
160
+ event_handlers << logger
161
+ end
162
+
163
+ def self.apply_extra_config_options(extra_config_options)
164
+ if extra_config_options
165
+ extra_parsed_options = extra_config_options.inject({}) do |memo, option|
166
+ # Sanity check value.
167
+ if option.empty? || !option.include?("=")
168
+ raise UnparsableConfigOption, "Unparsable config option #{option.inspect}"
169
+ end
170
+
171
+ # Split including whitespace if someone does truly odd like
172
+ # --config-option "foo = bar"
173
+ key, value = option.split(/\s*=\s*/, 2)
174
+
175
+ # Call to_sym because Chef::Config expects only symbol keys. Also
176
+ # runs a simple parse on the string for some common types.
177
+ memo[key.to_sym] = YAML.safe_load(value, permitted_classes: [Date])
178
+ memo
179
+ end
180
+ set_extra_config_options(extra_parsed_options)
181
+ end
182
+ end
183
+
184
+ # We use :[]= assignment here to not bypass any coercions that happen via mixlib-config writes_value callbacks
185
+ def self.set_extra_config_options(extra_parsed_options)
186
+ extra_parsed_options.each do |key, value|
187
+ self[key.to_sym] = value
188
+ end
189
+ end
190
+
191
+ # Config file to load (client.rb, knife.rb, etc. defaults set differently in knife, chef-client, etc.)
192
+ configurable(:config_file)
193
+
194
+ default(:config_dir) do
195
+ if config_file
196
+ PathHelper.dirname(PathHelper.canonical_path(config_file, false))
197
+ else
198
+ PathHelper.join(PathHelper.cleanpath(user_home), ChefUtils::Dist::Infra::USER_CONF_DIR, "")
199
+ end
200
+ end
201
+
202
+ default :formatters, []
203
+
204
+ # @param uri [String] the URI to validate
205
+ #
206
+ # @return [Boolean] is the URL valid
207
+ def self.is_valid_url?(uri)
208
+ url = uri.to_s.strip
209
+ %r{^http://} =~ url || %r{^https://} =~ url || /^chefzero:/ =~ url
210
+ end
211
+
212
+ # Override the config dispatch to set the value of multiple server options simultaneously
213
+ #
214
+ # @param [String] url String to be set for all of the chef-server-api URL's
215
+ #
216
+ configurable(:chef_server_url).writes_value do |uri|
217
+ unless is_valid_url? uri
218
+ raise ConfigurationError, "#{uri} is an invalid chef_server_url. The URL must start with http://, https://, or chefzero://."
219
+ end
220
+
221
+ uri.to_s.strip
222
+ end
223
+
224
+ # When you are using ActiveSupport, they monkey-patch 'daemonize' into Kernel.
225
+ # So while this is basically identical to what method_missing would do, we pull
226
+ # it up here and get a real method written so that things get dispatched
227
+ # properly.
228
+ configurable(:daemonize).writes_value { |v| v }
229
+
230
+ def self.expand_relative_paths(path)
231
+ unless path.nil?
232
+ if path.is_a?(String)
233
+ File.expand_path(path)
234
+ else
235
+ Array(path).map { |path| File.expand_path(path) }
236
+ end
237
+ end
238
+ end
239
+
240
+ configurable(:cookbook_path).writes_value { |path| expand_relative_paths(path) }
241
+
242
+ configurable(:chef_repo_path).writes_value { |path| expand_relative_paths(path) }
243
+
244
+ # The root where all local chef object data is stored. cookbooks, data bags,
245
+ # environments are all assumed to be in separate directories under this.
246
+ # chef-solo uses these directories for input data. knife commands
247
+ # that upload or download files (such as knife upload, knife role from file,
248
+ # etc.) work.
249
+ default :chef_repo_path do
250
+ if configuration[:cookbook_path]
251
+ if configuration[:cookbook_path].is_a?(String)
252
+ File.expand_path("..", configuration[:cookbook_path])
253
+ else
254
+ configuration[:cookbook_path].map do |path|
255
+ File.expand_path("..", path)
256
+ end
257
+ end
258
+ elsif configuration[:cookbook_artifact_path]
259
+ File.expand_path("..", configuration[:cookbook_artifact_path])
260
+ else
261
+ cache_path
262
+ end
263
+ end
264
+
265
+ def self.find_chef_repo_path(cwd)
266
+ # In local mode, we auto-discover the repo root by looking for a path with "cookbooks" under it.
267
+ # This allows us to run config-free.
268
+ path = cwd
269
+ until File.directory?(PathHelper.join(path, "cookbooks")) || File.directory?(PathHelper.join(path, "cookbook_artifacts"))
270
+ new_path = File.expand_path("..", path)
271
+ if new_path == path
272
+ ChefConfig.logger.warn("No cookbooks directory found at or above current directory. Assuming #{cwd}.")
273
+ return cwd
274
+ end
275
+ path = new_path
276
+ end
277
+ ChefConfig.logger.info("Auto-discovered #{ChefUtils::Dist::Infra::SHORT} repository at #{path}")
278
+ path
279
+ end
280
+
281
+ # @param child_path [String]
282
+ def self.derive_path_from_chef_repo_path(child_path)
283
+ if chef_repo_path.is_a?(String)
284
+ PathHelper.join(chef_repo_path, child_path)
285
+ else
286
+ chef_repo_path.uniq.map { |path| PathHelper.join(path, child_path) }
287
+ end
288
+ end
289
+
290
+ # Location of acls on disk. String or array of strings.
291
+ # Defaults to <chef_repo_path>/acls.
292
+ default(:acl_path) { derive_path_from_chef_repo_path("acls") }.writes_value { |path| expand_relative_paths(path) }
293
+
294
+ # Location of clients on disk. String or array of strings.
295
+ # Defaults to <chef_repo_path>/clients.
296
+ default(:client_path) { derive_path_from_chef_repo_path("clients") }.writes_value { |path| expand_relative_paths(path) }
297
+
298
+ # Location of client keys on disk. String or array of strings.
299
+ # Defaults to <chef_repo_path>/client_keys.
300
+ default(:client_key_path) { derive_path_from_chef_repo_path("client_keys") }.writes_value { |path| expand_relative_paths(path) }
301
+
302
+ # Location of containers on disk. String or array of strings.
303
+ # Defaults to <chef_repo_path>/containers.
304
+ default(:container_path) { derive_path_from_chef_repo_path("containers") }.writes_value { |path| expand_relative_paths(path) }
305
+
306
+ # Location of cookbook_artifacts on disk. String or array of strings.
307
+ # Defaults to <chef_repo_path>/cookbook_artifacts.
308
+ default(:cookbook_artifact_path) { derive_path_from_chef_repo_path("cookbook_artifacts") }.writes_value { |path| expand_relative_paths(path) }
309
+
310
+ # Location of cookbooks on disk. String or array of strings.
311
+ # Defaults to <chef_repo_path>/cookbooks. If chef_repo_path
312
+ # is not specified, this is set to /var/chef/cookbooks.
313
+ default(:cookbook_path) { derive_path_from_chef_repo_path("cookbooks") }
314
+
315
+ # Location of data bags on disk. String or array of strings.
316
+ # Defaults to <chef_repo_path>/data_bags.
317
+ default(:data_bag_path) { derive_path_from_chef_repo_path("data_bags") }.writes_value { |path| expand_relative_paths(path) }
318
+
319
+ # Location of environments on disk. String or array of strings.
320
+ # Defaults to <chef_repo_path>/environments.
321
+ default(:environment_path) { derive_path_from_chef_repo_path("environments") }.writes_value { |path| expand_relative_paths(path) }
322
+
323
+ # Location of groups on disk. String or array of strings.
324
+ # Defaults to <chef_repo_path>/groups.
325
+ default(:group_path) { derive_path_from_chef_repo_path("groups") }.writes_value { |path| expand_relative_paths(path) }
326
+
327
+ # Location of nodes on disk. String or array of strings.
328
+ # Defaults to <chef_repo_path>/nodes.
329
+ default(:node_path) { derive_path_from_chef_repo_path("nodes") }.writes_value { |path| expand_relative_paths(path) }
330
+
331
+ # Location of policies on disk. String or array of strings.
332
+ # Defaults to <chef_repo_path>/policies.
333
+ default(:policy_path) { derive_path_from_chef_repo_path("policies") }.writes_value { |path| expand_relative_paths(path) }
334
+
335
+ # Location of policy_groups on disk. String or array of strings.
336
+ # Defaults to <chef_repo_path>/policy_groups.
337
+ default(:policy_group_path) { derive_path_from_chef_repo_path("policy_groups") }.writes_value { |path| expand_relative_paths(path) }
338
+
339
+ # Location of roles on disk. String or array of strings.
340
+ # Defaults to <chef_repo_path>/roles.
341
+ default(:role_path) { derive_path_from_chef_repo_path("roles") }.writes_value { |path| expand_relative_paths(path) }
342
+
343
+ # Location of users on disk. String or array of strings.
344
+ # Defaults to <chef_repo_path>/users.
345
+ default(:user_path) { derive_path_from_chef_repo_path("users") }.writes_value { |path| expand_relative_paths(path) }
346
+
347
+ # DEPRECATED
348
+ default :enforce_path_sanity, false
349
+
350
+ # Enforce default paths by default for all APIs, not just the default internal shell_out
351
+ default :enforce_default_paths, false
352
+
353
+ # Formatted Chef Client output is a beta feature, disabled by default:
354
+ default :formatter, "null"
355
+
356
+ # The number of times the client should retry when registering with the server
357
+ default :client_registration_retries, 5
358
+
359
+ # An array of paths to search for knife exec scripts if they aren't in the current directory
360
+ default :script_path, []
361
+
362
+ # The root of all caches (checksums, cache and backup). If local mode is on,
363
+ # this is under the user's home directory.
364
+ default(:cache_path) do
365
+ if local_mode
366
+ PathHelper.join(config_dir, "local-mode-cache")
367
+ else
368
+ primary_cache_root = var_root_dir
369
+ primary_cache_path = var_chef_dir
370
+ # Use /var/chef as the cache path only if that folder exists and we can read and write
371
+ # into it, or /var exists and we can read and write into it (we'll create /var/chef later).
372
+ # Otherwise, we'll create .chef under the user's home directory and use that as
373
+ # the cache path.
374
+ unless path_accessible?(primary_cache_path) || path_accessible?(primary_cache_root)
375
+ secondary_cache_path = PathHelper.join(user_home, ChefUtils::Dist::Infra::USER_CONF_DIR)
376
+ secondary_cache_path = target_mode? ? PathHelper.join(secondary_cache_path, target_mode.host) : secondary_cache_path
377
+ ChefConfig.logger.trace("Unable to access cache at #{primary_cache_path}. Switching cache to #{secondary_cache_path}")
378
+ secondary_cache_path
379
+ else
380
+ target_mode? ? PathHelper.join(primary_cache_path, target_mode.host) : primary_cache_path
381
+ end
382
+ end
383
+ end
384
+
385
+ # Returns true only if the path exists and is readable and writeable for the user.
386
+ #
387
+ # @param path [String]
388
+ def self.path_accessible?(path)
389
+ File.exist?(path) && File.readable?(path) && File.writable?(path)
390
+ end
391
+
392
+ # Where cookbook files are stored on the server (by content checksum)
393
+ default(:checksum_path) { PathHelper.join(cache_path, "checksums") }
394
+
395
+ # Where chef's cache files should be stored
396
+ default(:file_cache_path) { PathHelper.join(cache_path, "cache") }.writes_value { |path| expand_relative_paths(path) }
397
+
398
+ # Where chef's cache files should be stored, used for bootstrap on unix filesystems
399
+ default(:unix_bootstrap_file_cache_path) { PathHelper.join("/var", ChefUtils::Dist::Infra::DIR_SUFFIX, "cache", windows: false) }
400
+
401
+ # Where chef's cache files should be stored, used for bootstrap on windows filesystems
402
+ default(:windows_bootstrap_file_cache_path) { PathHelper.join("C:", ChefUtils::Dist::Infra::DIR_SUFFIX, "cache", windows: true) }
403
+
404
+ # Where backups of chef-managed files should go
405
+ default(:file_backup_path) { PathHelper.join(cache_path, "backup") }
406
+
407
+ # Where chef's backup files should be stored, used for bootstrap on unix filesystems
408
+ default(:unix_bootstrap_file_backup_path) { PathHelper.join("/var", ChefUtils::Dist::Infra::DIR_SUFFIX, "backup", windows: false) }
409
+
410
+ # Where chef's backup files should be stored, used for bootstrap on windows filesystems
411
+ default(:windows_bootstrap_file_backup_path) { PathHelper.join("C:", ChefUtils::Dist::Infra::DIR_SUFFIX, "backup", windows: true) }
412
+
413
+ # The chef-client (or solo) lockfile.
414
+ #
415
+ # If your `file_cache_path` resides on a NFS (or non-flock()-supporting
416
+ # fs), it's recommended to set this to something like
417
+ # '/tmp/chef-client-running.pid'
418
+ default(:lockfile) { PathHelper.join(file_cache_path, "#{ChefUtils::Dist::Infra::CLIENT}-running.pid") }
419
+
420
+ ## Daemonization Settings ##
421
+ # What user should Chef run as?
422
+ default :user, nil
423
+ default :group, nil
424
+ default :umask, 0022
425
+
426
+ # Valid log_levels are:
427
+ # * :trace
428
+ # * :debug
429
+ # * :info
430
+ # * :warn
431
+ # * :fatal
432
+ # These work as you'd expect. There is also a special `:auto` setting.
433
+ # When set to :auto, Chef will auto adjust the log verbosity based on
434
+ # context. When a tty is available (usually because the user is running chef
435
+ # in a console), the log level is set to :warn, and output formatters are
436
+ # used as the primary mode of output. When a tty is not available, the
437
+ # logger is the primary mode of output, and the log level is set to :info
438
+ default :log_level, :auto
439
+
440
+ # Logging location as either an IO stream or string representing log file path
441
+ default :log_location, nil
442
+
443
+ # Using `force_formatter` causes chef to default to formatter output when STDOUT is not a tty
444
+ default :force_formatter, false
445
+
446
+ # Using `force_logger` causes chef to default to logger output when STDOUT is a tty
447
+ default :force_logger, false
448
+
449
+ # When set to true always print the stacktrace even if we haven't done -l debug
450
+ default :always_dump_stacktrace, false
451
+
452
+ # Using 'stream_execute_output' will have Chef always stream the execute output
453
+ default :stream_execute_output, false
454
+
455
+ # Using `show_download_progress` will display the overall progress
456
+ # of a remote file download
457
+ default :show_download_progress, false
458
+ # How often to update the progress meter, in percent
459
+ default :download_progress_interval, 10
460
+
461
+ default :http_retry_count, 5
462
+ default :http_retry_delay, 5
463
+ # Whether or not to send the Authorization header again on http redirects.
464
+ # As per the plan in https://github.com/chef/chef/pull/7006, this will be
465
+ # False in Chef 14, True in Chef 15, and will be removed entirely in Chef 16.
466
+ default :http_disable_auth_on_redirect, true
467
+
468
+ default :interval, nil
469
+ default :once, nil
470
+ default :json_attribs, nil
471
+ # toggle info level log items that can create a lot of output
472
+ default :verbose_logging, true
473
+ default :node_name, nil
474
+ default :diff_disabled, false
475
+ default :diff_filesize_threshold, 10000000
476
+ default :diff_output_threshold, 1000000
477
+
478
+ # This is true for "local mode" which uses a chef-zero server listening on
479
+ # localhost one way or another. This is true for both `chef-solo` (without
480
+ # the --legacy-mode flag) or `chef-client -z` methods of starting a client run.
481
+ #
482
+ default :local_mode, false
483
+
484
+ # Configures the mode of operation for ChefFS, which is applied to the
485
+ # ChefFS-based knife commands and chef-client's local mode. (ChefFS-based
486
+ # knife commands include: knife delete, knife deps, knife diff, knife down,
487
+ # knife edit, knife list, knife show, knife upload, and knife xargs.)
488
+ #
489
+ # Valid values are:
490
+ # * "static": ChefFS only manages objects that exist in a traditional Chef
491
+ # Repo as of Chef 11.
492
+ # * "everything": ChefFS manages all object types that existed on the OSS
493
+ # Chef 11 server.
494
+ # * "hosted_everything": ChefFS manages all object types as of the Chef 12
495
+ # Server, including RBAC objects and Policyfile objects (new to Chef 12).
496
+ default :repo_mode do
497
+ if local_mode && !chef_zero.osc_compat
498
+ "hosted_everything"
499
+ elsif %r{/+organizations/.+}.match?(chef_server_url)
500
+ "hosted_everything"
501
+ else
502
+ "everything"
503
+ end
504
+ end
505
+
506
+ default :pid_file, nil
507
+
508
+ # Whether Chef Zero local mode should bind to a port. All internal requests
509
+ # will go through the socketless code path regardless, so the socket is
510
+ # only needed if other processes will connect to the local mode server.
511
+ default :listen, false
512
+
513
+ config_context :chef_zero do
514
+ config_strict_mode true
515
+ default(:enabled) { ChefConfig::Config.local_mode }
516
+ default :host, "localhost"
517
+ default :port, 8889.upto(9999) # Will try ports from 8889-9999 until one works
518
+
519
+ # When set to a String, Chef Zero disables multitenant support. This is
520
+ # what you want when using Chef Zero to serve a single Chef Repo. Setting
521
+ # this to `false` enables multi-tenant.
522
+ default :single_org, "chef"
523
+
524
+ # Whether Chef Zero should operate in a mode analogous to OSS Chef Server
525
+ # 11 (true) or Chef Server 12 (false). Chef Zero can still serve
526
+ # policyfile objects in Chef 11 mode, as long as `repo_mode` is set to
527
+ # "hosted_everything". The primary differences are:
528
+ # * Chef 11 mode doesn't support multi-tenant, so there is no
529
+ # distinction between global and org-specific objects (since there are
530
+ # no orgs).
531
+ # * Chef 11 mode doesn't expose RBAC objects
532
+ default :osc_compat, false
533
+ end
534
+
535
+ # RFCxxx Target Mode support, value is the name of a remote device to Chef against
536
+ # --target exists as a shortcut to enabling target_mode and setting the host
537
+ configurable(:target)
538
+
539
+ config_context :target_mode do
540
+ config_strict_mode false # we don't want to have to add all train configuration keys here
541
+ default :enabled, false
542
+ default :protocol, "ssh"
543
+ # typical additional keys: host, user, password
544
+ end
545
+
546
+ def self.target_mode?
547
+ target_mode.enabled
548
+ end
549
+
550
+ default :chef_server_url, "https://localhost:443"
551
+
552
+ default(:chef_server_root) do
553
+ # if the chef_server_url is a path to an organization, aka
554
+ # 'some_url.../organizations/*' then remove the '/organization/*' by default
555
+ if %r{/organizations/\S*$}.match?(configuration[:chef_server_url])
556
+ configuration[:chef_server_url].split("/")[0..-3].join("/")
557
+ elsif configuration[:chef_server_url] # default to whatever chef_server_url is
558
+ configuration[:chef_server_url]
559
+ else
560
+ "https://localhost:443"
561
+ end
562
+ end
563
+
564
+ default :rest_timeout, 300
565
+
566
+ # This solo setting is now almost entirely useless. It is set to true if chef-solo was
567
+ # invoked that way from the command-line (i.e. from Application::Solo as opposed to
568
+ # Application::Client). The more useful information is contained in the :solo_legacy_mode
569
+ # vs the :local_mode flags which will be set to true or false depending on how solo was
570
+ # invoked and actually change more of the behavior. There might be slight differences in
571
+ # the behavior of :local_mode due to the behavioral differences in Application::Solo vs.
572
+ # Application::Client and `chef-solo` vs `chef-client -z`, but checking this value and
573
+ # switching based on it is almost certainly doing the wrong thing and papering over
574
+ # bugs that should be fixed in one or the other class, and will be brittle and destined
575
+ # to break in the future (and not necessarily on a major version bump). Checking this value
576
+ # is also not sufficient to determine if we are not running against a server since this can
577
+ # be unset but :local_mode may be set. It would be accurate to check both :solo and :local_mode
578
+ # to determine if we're not running against a server, but the more semantically accurate test
579
+ # is going to be combining :solo_legacy_mode and :local_mode.
580
+ #
581
+ # TL;DR: `if Chef::Config[:solo]` is almost certainly buggy code, you should use:
582
+ # `if Chef::Config[:local_mode] || Chef::Config[:solo_legacy_mode]`
583
+ #
584
+ # @api private
585
+ default :solo, false
586
+
587
+ # This is true for old chef-solo legacy mode without any chef-zero server (chef-solo --legacy-mode)
588
+ default :solo_legacy_mode, false
589
+
590
+ default :splay, nil
591
+ default :why_run, false
592
+ default :color, false
593
+ default :client_fork, nil
594
+ default :ez, false
595
+ default :enable_reporting, true
596
+ default :enable_reporting_url_fatals, false
597
+
598
+ # Chef only needs ohai to run the hostname plugin for the most basic
599
+ # functionality. If the rest of the ohai plugins are not needed (like in
600
+ # most of our testing scenarios)
601
+ default :minimal_ohai, false
602
+
603
+ # When consuming Ohai plugins from cookbook segments, we place those plugins in this directory.
604
+ # Subsequent chef client runs will wipe and re-populate the directory to ensure cleanliness
605
+ default(:ohai_segment_plugin_path) { PathHelper.join(config_dir, "ohai", "cookbook_plugins") }
606
+
607
+ ###
608
+ # Policyfile Settings
609
+ #
610
+ # Policyfile is a feature where a node gets its run list and cookbook
611
+ # version set from a single document on the server instead of expanding the
612
+ # run list and having the server compute the cookbook version set based on
613
+ # environment constraints.
614
+ #
615
+ # Policyfiles are auto-versioned. The user groups nodes by `policy_name`,
616
+ # which generally describes a hosts's functional role, and `policy_group`,
617
+ # which generally groups nodes by deployment phase (a.k.a., "environment").
618
+ # The Chef Server maps a given set of `policy_name` plus `policy_group` to
619
+ # a particular revision of a policy.
620
+
621
+ default :policy_name, nil
622
+ default :policy_group, nil
623
+
624
+ # Policyfiles can have multiple run lists, via the named run list feature.
625
+ # Generally this will be set by a CLI option via Chef::Application::Client,
626
+ # but it could be set in client.rb if desired.
627
+
628
+ default :named_run_list, nil
629
+
630
+ # Policyfiles can be used in a native mode (default) or compatibility mode.
631
+ # Native mode requires Chef Server 12.1 (it can be enabled via feature flag
632
+ # on some prior versions). In native mode, policies and associated
633
+ # cookbooks are accessed via feature-specific APIs. In compat mode,
634
+ # policies are stored as data bags and cookbooks are stored at the
635
+ # cookbooks/ endpoint. Compatibility mode can be dangerous on existing Chef
636
+ # Servers; it's recommended to upgrade your Chef Server rather than use
637
+ # compatibility mode. Compatibility mode remains available so you can use
638
+ # policyfiles with servers that don't yet support the native endpoints.
639
+ default :policy_document_native_api, true
640
+
641
+ # When policyfiles are used in compatibility mode, `policy_name` and
642
+ # `policy_group` are instead specified using a combined configuration
643
+ # setting, `deployment_group`. For example, if policy_name should be
644
+ # "webserver" and policy_group should be "staging", then `deployment_group`
645
+ # should be set to "webserver-staging", which is the name of the data bag
646
+ # item that the policy will be stored as. NOTE: this setting only has an
647
+ # effect if `policy_document_native_api` is set to `false`.
648
+ default :deployment_group, nil
649
+
650
+ # When using policyfiles you can optionally set it to read the node.run_list
651
+ # from the server and have that override the policyfile run_list or the
652
+ # named_run_list set in config. With policyfiles there is no depsolving done
653
+ # on the run_list items so every item in the run_list must be in the set of
654
+ # cookbooks pushed to the node. This enables flows where the node can change
655
+ # its run_list and have it persist or to bootstrap nodes with the -j flag. If
656
+ # no run_list is set on the server node object then the configured named_run_list
657
+ # or run_list out of the policy is used.
658
+ default :policy_persist_run_list, false
659
+
660
+ # Set these to enable SSL authentication / mutual-authentication
661
+ # with the server
662
+
663
+ # Client side SSL cert/key for mutual auth
664
+ default :ssl_client_cert, nil
665
+ default :ssl_client_key, nil
666
+
667
+ # Whether or not to verify the SSL cert for all HTTPS requests. When set to
668
+ # :verify_peer (default), all HTTPS requests will be validated regardless of other
669
+ # SSL verification settings. When set to :verify_none no HTTPS requests will
670
+ # be validated.
671
+ default :ssl_verify_mode, :verify_peer
672
+
673
+ # Needed to coerce string value to a symbol when loading settings from the
674
+ # credentials toml files which doesn't allow ruby symbol values
675
+ configurable(:ssl_verify_mode).writes_value do |value|
676
+ if value.is_a?(String) && value[0] == ":"
677
+ value[1..].to_sym
678
+ else
679
+ value.to_sym
680
+ end
681
+ end
682
+
683
+ # Whether or not to verify the SSL cert for HTTPS requests to the Chef
684
+ # server API. If set to `true`, the server's cert will be validated
685
+ # regardless of the :ssl_verify_mode setting. This is set to `true` when
686
+ # running in local-mode.
687
+ # NOTE: This is a workaround until verify_peer is enabled by default.
688
+ default(:verify_api_cert) { ChefConfig::Config.local_mode }
689
+
690
+ # Path to the default CA bundle files.
691
+ default :ssl_ca_path, nil
692
+ default(:ssl_ca_file) do
693
+ if ChefUtils.windows? && embedded_dir
694
+ cacert_path = File.join(embedded_dir, "ssl/certs/cacert.pem")
695
+ cacert_path if File.exist?(cacert_path)
696
+ else
697
+ nil
698
+ end
699
+ end
700
+
701
+ # A directory that contains additional SSL certificates to trust. Any
702
+ # certificates in this directory will be added to whatever CA bundle ruby
703
+ # is using. Use this to add self-signed certs for your Chef Server or local
704
+ # HTTP file servers.
705
+ default(:trusted_certs_dir) { PathHelper.join(config_dir, "trusted_certs") }
706
+
707
+ # A directory that contains additional configuration scripts to load for chef-client
708
+ default(:client_d_dir) { PathHelper.join(config_dir, "client.d") }
709
+
710
+ # A directory that contains additional configuration scripts to load for solo
711
+ default(:solo_d_dir) { PathHelper.join(config_dir, "solo.d") }
712
+
713
+ # A directory that contains additional configuration scripts to load for
714
+ # the workstation config
715
+ default(:config_d_dir) { PathHelper.join(config_dir, "config.d") }
716
+
717
+ # Where should chef-solo download recipes from?
718
+ default :recipe_url, nil
719
+
720
+ # Set to true if Chef is to set OpenSSL to run in FIPS mode
721
+ default(:fips) do
722
+ # CHEF_FIPS is used in testing to override checking for system level
723
+ # enablement. There are 3 possible values that this variable may have:
724
+ # nil - no override and the system will be checked
725
+ # empty - FIPS is NOT enabled
726
+ # a non empty value - FIPS is enabled
727
+ if ENV["CHEF_FIPS"] == ""
728
+ false
729
+ else
730
+ !ENV["CHEF_FIPS"].nil? || ChefConfig.fips?
731
+ end
732
+ end
733
+
734
+ # Initialize openssl
735
+ def self.init_openssl
736
+ if fips
737
+ enable_fips_mode
738
+ end
739
+ end
740
+
741
+ # Sets the version of the signed header authentication protocol to use (see
742
+ # the 'mixlib-authorization' project for more detail). Currently, versions
743
+ # 1.0, 1.1, and 1.3 are available.
744
+ default :authentication_protocol_version do
745
+ if fips || ssh_agent_signing
746
+ "1.3"
747
+ else
748
+ "1.1"
749
+ end
750
+ end
751
+
752
+ # This key will be used to sign requests to the Chef server. This location
753
+ # must be writable by Chef during initial setup when generating a client
754
+ # identity on the server.
755
+ #
756
+ # The chef-server will look up the public key for the client using the
757
+ # `node_name` of the client.
758
+ #
759
+ # If chef-zero is enabled, this defaults to nil (no authentication).
760
+ default(:client_key) do
761
+ if chef_zero.enabled
762
+ nil
763
+ elsif target_mode?
764
+ PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/client.pem")
765
+ else
766
+ PathHelper.cleanpath("#{etc_chef_dir}/client.pem")
767
+ end
768
+ end
769
+
770
+ # A credentials file may contain a complete client key, rather than the path
771
+ # to one.
772
+ #
773
+ # We'll use this preferentially.
774
+ default :client_key_contents, nil
775
+
776
+ # We want to get all certificates OFF disk and into secure storage. This flag
777
+ # removes the client.pem from disk and a replacement is put into Keychain or the Certstore
778
+ # Then the public key from the new cert is pushed to Chef Server for authentication
779
+ default :migrate_key_to_keystore, false
780
+
781
+ # When registering the client, should we allow the client key location to
782
+ # be a symlink? eg: /etc/chef/client.pem -> /etc/chef/prod-client.pem
783
+ # If the path of the key goes through a directory like /tmp this should
784
+ # never be set to true or its possibly an easily exploitable security hole.
785
+ default :follow_client_key_symlink, false
786
+
787
+ # Enable ssh-agent signing mode. This requires {client_key} be set to a
788
+ # public key rather than the usual private key.
789
+ default :ssh_agent_signing, false
790
+
791
+ # This secret is used to decrypt encrypted data bag items.
792
+ default(:encrypted_data_bag_secret) do
793
+ if target_mode? && File.exist?(PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/encrypted_data_bag_secret"))
794
+ PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/encrypted_data_bag_secret")
795
+ elsif File.exist?(PathHelper.cleanpath("#{etc_chef_dir}/encrypted_data_bag_secret"))
796
+ PathHelper.cleanpath("#{etc_chef_dir}/encrypted_data_bag_secret")
797
+ else
798
+ nil
799
+ end
800
+ end
801
+
802
+ # As of Chef 13.0, version "3" is the default encrypted data bag item
803
+ # format.
804
+ #
805
+ default :data_bag_encrypt_version, 3
806
+
807
+ # When reading data bag items, any supported version is accepted. However,
808
+ # if all encrypted data bags have been generated with the version 2 format,
809
+ # it is recommended to disable support for earlier formats to improve
810
+ # security. For example, the version 2 format is identical to version 1
811
+ # except for the addition of an HMAC, so an attacker with MITM capability
812
+ # could downgrade an encrypted data bag to version 1 as part of an attack.
813
+ default :data_bag_decrypt_minimum_version, 0
814
+
815
+ # If there is no file in the location given by `client_key`, chef-client
816
+ # will temporarily use the "validator" identity to generate one. If the
817
+ # `client_key` is not present and the `validation_key` is also not present,
818
+ # chef-client will not be able to authenticate to the server.
819
+ #
820
+ # The `validation_key` is never used if the `client_key` exists.
821
+ #
822
+ # If chef-zero is enabled, this defaults to nil (no authentication).
823
+ default(:validation_key) { chef_zero.enabled ? nil : PathHelper.cleanpath("#{etc_chef_dir}/validation.pem") }
824
+ default :validation_client_name do
825
+ # If the URL is set and looks like a normal Chef Server URL, extract the
826
+ # org name and use that as part of the default.
827
+ if chef_server_url.to_s =~ %r{/organizations/(.*)$}
828
+ "#{$1}-validator"
829
+ else
830
+ "#{ChefUtils::Dist::Infra::SHORT}-validator"
831
+ end
832
+ end
833
+
834
+ default :validation_key_contents, nil
835
+ # When creating a new client via the validation_client account, Chef 11
836
+ # servers allow the client to generate a key pair locally and send the
837
+ # public key to the server. This is more secure and helps offload work from
838
+ # the server, enhancing scalability. If enabled and the remote server
839
+ # implements only the Chef 10 API, client registration will not work
840
+ # properly.
841
+ #
842
+ # The default value is `true`. Set to `false` to disable client-side key
843
+ # generation (server generates client keys).
844
+ default(:local_key_generation) { true }
845
+
846
+ # Zypper package provider gpg checks. Set to false to disable package
847
+ # gpg signature checking globally. This will warn you that it is a
848
+ # bad thing to do.
849
+ default :zypper_check_gpg, true
850
+
851
+ # Report Handlers
852
+ default :report_handlers, []
853
+
854
+ # Event Handlers
855
+ default :event_handlers, []
856
+
857
+ default :disable_event_loggers, false
858
+
859
+ # Exception Handlers
860
+ default :exception_handlers, []
861
+
862
+ # Start handlers
863
+ default :start_handlers, []
864
+
865
+ # Syntax Check Cache. Knife keeps track of files that is has already syntax
866
+ # checked by storing files in this directory. `syntax_check_cache_path` is
867
+ # the new (and preferred) configuration setting. If not set, knife will
868
+ # fall back to using cache_options[:path], which is deprecated but exists in
869
+ # many client configs generated by pre-Chef-11 bootstrappers.
870
+ default(:syntax_check_cache_path) { cache_options[:path] }.writes_value { |path| expand_relative_paths(path) }
871
+
872
+ # Deprecated:
873
+ # Move this to the default value of syntax_cache_path when this is removed.
874
+ default(:cache_options) { { path: PathHelper.join(config_dir, "syntaxcache") } }
875
+
876
+ # Whether errors should be raised for deprecation warnings. When set to
877
+ # `false` (the default setting), a warning is emitted but code using
878
+ # deprecated methods/features/etc. should work normally otherwise. When set
879
+ # to `true`, usage of deprecated methods/features will raise a
880
+ # `DeprecatedFeatureError`. This is used by Chef's tests to ensure that
881
+ # deprecated functionality is not used internally by Chef. End users
882
+ # should generally leave this at the default setting (especially in
883
+ # production), but it may be useful when testing cookbooks or other code if
884
+ # the user wishes to aggressively address deprecations.
885
+ default(:treat_deprecation_warnings_as_errors) do
886
+ # Using an environment variable allows this setting to be inherited in
887
+ # tests that spawn new processes.
888
+ ENV.key?("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
889
+ end
890
+
891
+ # Which deprecations warnings to silence. Can be set to `true` to silence
892
+ # all warnings, or an array of strings like either `"deprecation_type"` or
893
+ # `"filename.rb:lineno"`.
894
+ default :silence_deprecation_warnings, []
895
+
896
+ # Whether the resource count should be updated for log resource
897
+ # on running chef-client
898
+ default :count_log_resource_updates, false
899
+
900
+ # The selected profile when using credentials.
901
+ default :profile, nil
902
+
903
+ default :chef_guid_path do
904
+ PathHelper.join(config_dir, "#{ChefUtils::Dist::Infra::SHORT}_guid")
905
+ end
906
+
907
+ default :chef_guid, nil
908
+
909
+ # knife configuration data
910
+ config_context :knife do
911
+ default :hints, {}
912
+ end
913
+
914
+ def self.set_defaults_for_windows
915
+ # Those lists of regular expressions define what chef considers a
916
+ # valid user and group name
917
+ # From http://technet.microsoft.com/en-us/library/cc776019(WS.10).aspx
918
+ principal_valid_regex_part = '[^"\/\\\\\[\]\:;|=,+*?<>]+'
919
+ default :user_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
920
+ default :group_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
921
+
922
+ default :fatal_windows_admin_check, false
923
+ end
924
+
925
+ def self.set_defaults_for_nix
926
+ # Those lists of regular expressions define what chef considers a
927
+ # valid user and group name
928
+ #
929
+ # user/group cannot start with '-', '+' or '~'
930
+ # user/group cannot contain ':', ',' or non-space-whitespace or null byte
931
+ # everything else is allowed (UTF-8, spaces, etc) and we delegate to your O/S useradd program to barf or not
932
+ # copies: http://anonscm.debian.org/viewvc/pkg-shadow/debian/trunk/debian/patches/506_relaxed_usernames?view=markup
933
+ default :user_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
934
+ default :group_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
935
+ end
936
+
937
+ # Those lists of regular expressions define what chef considers a
938
+ # valid user and group name
939
+ if ChefUtils.windows?
940
+ set_defaults_for_windows
941
+ else
942
+ set_defaults_for_nix
943
+ end
944
+
945
+ # This provides a hook which rspec can stub so that we can avoid twiddling
946
+ # global state in tests.
947
+ def self.env
948
+ ENV
949
+ end
950
+
951
+ def self.windows_home_path
952
+ ChefConfig.logger.deprecation("Chef::Config.windows_home_path is now deprecated. Consider using Chef::Util::PathHelper.home instead.")
953
+ PathHelper.home
954
+ end
955
+
956
+ # returns a platform specific path to the user home dir if set, otherwise default to current directory.
957
+ default( :user_home ) { PathHelper.home || Dir.pwd }
958
+
959
+ # Enable file permission fixup for selinux. Fixup will be done
960
+ # only if selinux is enabled in the system.
961
+ default :enable_selinux_file_permission_fixup, true
962
+
963
+ # Use atomic updates (i.e. move operation) while updating contents
964
+ # of the files resources. When set to false copy operation is
965
+ # used to update files.
966
+ #
967
+ # NOTE: CHANGING THIS SETTING MAY CAUSE CORRUPTION, DATA LOSS AND
968
+ # INSTABILITY.
969
+ #
970
+ default :file_atomic_update, true
971
+
972
+ # There are 3 possible values for this configuration setting.
973
+ # true => file staging is done in the destination directory
974
+ # false => file staging is done via tempfiles under ENV['TMP']
975
+ # :auto => file staging will try using destination directory if possible and
976
+ # will fall back to ENV['TMP'] if destination directory is not usable.
977
+ #
978
+ default :file_staging_uses_destdir, :auto
979
+
980
+ # Exit if another run is in progress and the chef-client is unable to
981
+ # get the lock before time expires. If nil, no timeout is enforced. (Exits
982
+ # immediately if 0.)
983
+ #
984
+ default :run_lock_timeout, nil
985
+
986
+ # Number of worker threads for syncing cookbooks in parallel. Increasing
987
+ # this number can result in gateway errors from the server (namely 503 and 504).
988
+ # If you are seeing this behavior while using the default setting, reducing
989
+ # the number of threads will help.
990
+ #
991
+ default :cookbook_sync_threads, 10
992
+
993
+ # True if all resources by default default to unified mode, with all resources
994
+ # applying in "compile" mode, with no "converge" mode. False is backwards compatible
995
+ # setting for Chef 11-15 behavior. This will break forward notifications.
996
+ #
997
+ default :resource_unified_mode_default, true
998
+
999
+ # At the beginning of the Chef Client run, the cookbook manifests are downloaded which
1000
+ # contain URLs for every file in every relevant cookbook. Most of the files
1001
+ # (recipes, resources, providers, libraries, etc) are immediately synchronized
1002
+ # at the start of the run. The handling of "files" and "templates" directories,
1003
+ # however, have two modes of operation. They can either all be downloaded immediately
1004
+ # at the start of the run (no_lazy_load==true) or else they can be lazily loaded as
1005
+ # cookbook_file or template resources are converged which require them (no_lazy_load==false).
1006
+ #
1007
+ # The advantage of lazily loading these files is that unnecessary files are not
1008
+ # synchronized. This may be useful to users with large files checked into cookbooks which
1009
+ # are only selectively downloaded to a subset of clients which use the cookbook. However,
1010
+ # better solutions are to either isolate large files into individual cookbooks and only
1011
+ # include those cookbooks in the run lists of the servers that need them -- or move to
1012
+ # using remote_file and a more appropriate backing store like S3 for large file
1013
+ # distribution.
1014
+ #
1015
+ # The disadvantages of lazily loading files are that users some time find it
1016
+ # confusing that their cookbooks are not fully synchronized to the cache initially,
1017
+ # and more importantly the time-sensitive URLs which are in the manifest may time
1018
+ # out on long Chef runs before the resource that uses the file is converged
1019
+ # (leading to many confusing 403 errors on template/cookbook_file resources).
1020
+ #
1021
+ default :no_lazy_load, true
1022
+
1023
+ # A array of attributes you want sent over the wire when node
1024
+ # data is saved. The default setting is nil, which collects all data.
1025
+ # NOTE: Setting to [] will not collect ANY data to save.
1026
+ default :allowed_automatic_attributes, nil
1027
+ default :allowed_default_attributes, nil
1028
+ default :allowed_normal_attributes, nil
1029
+ default :allowed_override_attributes, nil
1030
+
1031
+ # An array of attributes you do not want to send over the
1032
+ # wire when node data is saved
1033
+ # The default setting is nil, which collects all data.
1034
+ # NOTE: Setting to [] will still collect all data to save
1035
+ default :blocked_automatic_attributes, nil
1036
+ default :blocked_default_attributes, nil
1037
+ default :blocked_normal_attributes, nil
1038
+ default :blocked_override_attributes, nil
1039
+
1040
+ # deprecated config options that will be removed in Chef Infra Client 18
1041
+ default :automatic_attribute_blacklist, nil
1042
+ default :default_attribute_blacklist, nil
1043
+ default :normal_attribute_blacklist, nil
1044
+ default :override_attribute_blacklist, nil
1045
+ default :automatic_attribute_whitelist, nil
1046
+ default :default_attribute_whitelist, nil
1047
+ default :normal_attribute_whitelist, nil
1048
+ default :override_attribute_whitelist, nil
1049
+
1050
+ # Pull down all the rubygems versions from rubygems and cache them the first time we do a gem_package or
1051
+ # chef_gem install. This is memory-expensive and will grow without bounds, but will reduce network
1052
+ # round trips.
1053
+ default :rubygems_cache_enabled, false
1054
+
1055
+ config_context :windows_service do
1056
+ # Set `watchdog_timeout` to the number of seconds to wait for a chef-client run
1057
+ # to finish
1058
+ default :watchdog_timeout, 2 * (60 * 60) # 2 hours
1059
+ end
1060
+
1061
+ # Add an empty and non-strict config_context for chefdk and chefcli.
1062
+ # This lets the user have code like `chefdk.generator_cookbook "/path/to/cookbook"` or
1063
+ # `chefcli[:generator_cookbook] = "/path/to/cookbook"` in their config.rb,
1064
+ # and it will be ignored by tools like knife and ohai. ChefDK and ChefCLI
1065
+ # themselves can define the config options it accepts and enable strict mode,
1066
+ # and that will only apply when running `chef` commands.
1067
+ config_context :chefdk do
1068
+ end
1069
+
1070
+ config_context :chefcli do
1071
+ end
1072
+
1073
+ # Configuration options for Data Collector reporting. These settings allow
1074
+ # the user to configure where to send their Data Collector data, what token
1075
+ # to send, and whether Data Collector should report its findings in client
1076
+ # mode vs. solo mode.
1077
+ config_context :data_collector do
1078
+ # Full URL to the endpoint that will receive our data. If nil, the
1079
+ # data collector will not run.
1080
+ # Ex: http://my-data-collector.mycompany.com/ingest
1081
+ default(:server_url) do
1082
+ if config_parent.solo_legacy_mode || config_parent.local_mode
1083
+ nil
1084
+ else
1085
+ File.join(config_parent.chef_server_url, "/data-collector")
1086
+ end
1087
+ end
1088
+
1089
+ # An optional pre-shared token to pass as an HTTP header (x-data-collector-token)
1090
+ # that can be used to determine whether or not the poster of this
1091
+ # run data should be trusted.
1092
+ # Ex: some-uuid-here
1093
+ default :token, nil
1094
+
1095
+ # The Chef mode during which Data Collector is allowed to function. This
1096
+ # can be used to run Data Collector only when running as Chef Solo but
1097
+ # not when using Chef Client.
1098
+ # Options: :solo (for both Solo Legacy Mode and Client Local Mode), :client, :both
1099
+ default :mode, :both
1100
+
1101
+ # When the Data Collector cannot send the "starting a run" message to
1102
+ # the Data Collector server, the Data Collector will be disabled for that
1103
+ # run. In some situations, such as highly-regulated environments, it
1104
+ # may be more reasonable to prevent Chef from performing the actual run.
1105
+ # In these situations, setting this value to true will cause the Chef
1106
+ # run to raise an exception before starting any converge activities.
1107
+ default :raise_on_failure, false
1108
+
1109
+ # A user-supplied Organization string that can be sent in payloads
1110
+ # generated by the DataCollector when Chef is run in Solo mode. This
1111
+ # allows users to associate their Solo nodes with faux organizations
1112
+ # without the nodes being connected to an actual Chef Server.
1113
+ default :organization, "#{ChefUtils::Dist::Infra::SHORT}_solo"
1114
+ end
1115
+
1116
+ configurable(:http_proxy)
1117
+ configurable(:http_proxy_user)
1118
+ configurable(:http_proxy_pass)
1119
+ configurable(:https_proxy)
1120
+ configurable(:https_proxy_user)
1121
+ configurable(:https_proxy_pass)
1122
+ configurable(:ftp_proxy)
1123
+ configurable(:ftp_proxy_user)
1124
+ configurable(:ftp_proxy_pass)
1125
+ configurable(:no_proxy)
1126
+
1127
+ # Public method that users should call to export proxies to the appropriate
1128
+ # environment variables. This method should be called after the config file is
1129
+ # parsed and loaded.
1130
+ # TODO add some post-file-parsing logic that automatically calls this so
1131
+ # users don't have to
1132
+ def self.export_proxies
1133
+ export_proxy("http", http_proxy, http_proxy_user, http_proxy_pass) if key?(:http_proxy) && http_proxy
1134
+ export_proxy("https", https_proxy, https_proxy_user, https_proxy_pass) if key?(:https_proxy) && https_proxy
1135
+ export_proxy("ftp", ftp_proxy, ftp_proxy_user, ftp_proxy_pass) if key?(:ftp_proxy) && ftp_proxy
1136
+ export_no_proxy(no_proxy) if key?(:no_proxy) && no_proxy
1137
+ end
1138
+
1139
+ # Builds a proxy uri and exports it to the appropriate environment variables. Examples:
1140
+ # http://username:password@hostname:port
1141
+ # https://username@hostname:port
1142
+ # ftp://hostname:port
1143
+ # when
1144
+ # scheme = "http", "https", or "ftp"
1145
+ # hostport = hostname:port or scheme://hostname:port
1146
+ # user = username
1147
+ # pass = password
1148
+ # @api private
1149
+ def self.export_proxy(scheme, path, user, pass)
1150
+ # Character classes for Addressable
1151
+ # See https://www.ietf.org/rfc/rfc3986.txt 3.2.1
1152
+ # The user part may not have a : in it
1153
+ user_class = Addressable::URI::CharacterClasses::UNRESERVED + Addressable::URI::CharacterClasses::SUB_DELIMS
1154
+ # The password part may have any valid USERINFO characters
1155
+ password_class = user_class + "\\:"
1156
+
1157
+ path = "#{scheme}://#{path}" unless path.include?("://")
1158
+ # URI.split returns the following parts:
1159
+ # [scheme, userinfo, host, port, registry, path, opaque, query, fragment]
1160
+ uri = Addressable::URI.encode(path, Addressable::URI)
1161
+
1162
+ if user && !user.empty?
1163
+ userinfo = Addressable::URI.encode_component(user, user_class)
1164
+ if pass
1165
+ userinfo << ":#{Addressable::URI.encode_component(pass, password_class)}"
1166
+ end
1167
+ uri.userinfo = userinfo
1168
+ end
1169
+
1170
+ path = uri.to_s
1171
+ ENV["#{scheme}_proxy".downcase] = path unless ENV["#{scheme}_proxy".downcase]
1172
+ ENV["#{scheme}_proxy".upcase] = path unless ENV["#{scheme}_proxy".upcase]
1173
+ end
1174
+
1175
+ # @api private
1176
+ def self.export_no_proxy(value)
1177
+ ENV["no_proxy"] = value unless ENV["no_proxy"]
1178
+ ENV["NO_PROXY"] = value unless ENV["NO_PROXY"]
1179
+ end
1180
+
1181
+ # Given a scheme, host, and port, return the correct proxy URI based on the
1182
+ # set environment variables, unless excluded by no_proxy, in which case nil
1183
+ # is returned
1184
+ def self.proxy_uri(scheme, host, port)
1185
+ proxy_env_var = ENV["#{scheme}_proxy"].to_s.strip
1186
+
1187
+ # Check if the proxy string contains a scheme. If not, add the url's scheme to the
1188
+ # proxy before parsing. The regex /^.*:\/\// matches, for example, http://. Reusing proxy
1189
+ # here since we are really just trying to get the string built correctly.
1190
+ proxy = unless proxy_env_var.empty?
1191
+ if %r{^.*://}.match?(proxy_env_var)
1192
+ URI.parse(proxy_env_var)
1193
+ else
1194
+ URI.parse("#{scheme}://#{proxy_env_var}")
1195
+ end
1196
+ end
1197
+
1198
+ return proxy unless fuzzy_hostname_match_any?(host, ENV["no_proxy"])
1199
+ end
1200
+
1201
+ # Chef requires an English-language UTF-8 locale to function properly. We attempt
1202
+ # to use the 'locale -a' command and search through a list of preferences until we
1203
+ # find one that we can use. On Ubuntu systems we should find 'C.UTF-8' and be
1204
+ # able to use that even if there is no English locale on the server, but Mac, Solaris,
1205
+ # AIX, etc do not have that locale. We then try to find an English locale and fall
1206
+ # back to 'C' if we do not. The choice of fallback is pick-your-poison. If we try
1207
+ # to do the work to return a non-US UTF-8 locale then we fail inside of providers when
1208
+ # things like 'svn info' return Japanese and we can't parse them. OTOH, if we pick 'C' then
1209
+ # we will blow up on UTF-8 characters. Between the warn we throw and the Encoding
1210
+ # exception that ruby will throw it is more obvious what is broken if we drop UTF-8 by
1211
+ # default rather than drop English.
1212
+ #
1213
+ # If there is no 'locale -a' then we return 'en_US.UTF-8' since that is the most commonly
1214
+ # available English UTF-8 locale. However, all modern POSIXen should support 'locale -a'.
1215
+ def self.guess_internal_locale
1216
+ # https://github.com/chef/chef/issues/2181
1217
+ # Some systems have the `locale -a` command, but the result has
1218
+ # invalid characters for the default encoding.
1219
+ #
1220
+ # For example, on CentOS 6 with ENV['LANG'] = "en_US.UTF-8",
1221
+ # `locale -a`.split fails with ArgumentError invalid UTF-8 encoding.
1222
+ cmd = Mixlib::ShellOut.new("locale -a").run_command
1223
+ cmd.error!
1224
+ locales = cmd.stdout.split
1225
+ case
1226
+ when locales.include?("C.UTF-8")
1227
+ "C.UTF-8"
1228
+ when locales.include?("en_US.UTF-8"), locales.include?("en_US.utf8")
1229
+ "en_US.UTF-8"
1230
+ when locales.include?("en.UTF-8")
1231
+ "en.UTF-8"
1232
+ else
1233
+ # Will match en_ZZ.UTF-8, en_ZZ.utf-8, en_ZZ.UTF8, en_ZZ.utf8
1234
+ guesses = locales.grep(/^en_.*UTF-?8$/i)
1235
+ unless guesses.empty?
1236
+ guessed_locale = guesses.first
1237
+ # Transform into the form en_ZZ.UTF-8
1238
+ guessed_locale.gsub(/UTF-?8$/i, "UTF-8")
1239
+ else
1240
+ ChefConfig.logger.warn "Please install an English UTF-8 locale for #{ChefUtils::Dist::Infra::PRODUCT} to use, falling back to C locale and disabling UTF-8 support."
1241
+ "C"
1242
+ end
1243
+ end
1244
+ rescue
1245
+ if ChefUtils.windows?
1246
+ ChefConfig.logger.trace "Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else."
1247
+ else
1248
+ ChefConfig.logger.trace "No usable locale -a command found, assuming you have en_US.UTF-8 installed."
1249
+ end
1250
+ "en_US.UTF-8"
1251
+ end
1252
+
1253
+ default :internal_locale, guess_internal_locale
1254
+
1255
+ # Force UTF-8 Encoding, for when we fire up in the 'C' locale or other strange locales (e.g.
1256
+ # japanese windows encodings). If we do not do this, then knife upload will fail when a cookbook's
1257
+ # README.md has UTF-8 characters that do not encode in whatever surrounding encoding we have been
1258
+ # passed. Effectively, the Chef Ecosystem is globally UTF-8 by default. Anyone who wants to be
1259
+ # able to upload Shift_JIS or ISO-8859-1 files needs to mark *those* files explicitly with
1260
+ # magic tags to make ruby correctly identify the encoding being used. Changing this default will
1261
+ # break Chef community cookbooks and is very highly discouraged.
1262
+ default :ruby_encoding, Encoding::UTF_8
1263
+
1264
+ # can be set to a string or array of strings for URIs to set as rubygems sources
1265
+ default :rubygems_url, nil
1266
+
1267
+ # globally sets the default of the clear_sources property on the gem_package and chef_gem resources
1268
+ default :clear_gem_sources, nil
1269
+
1270
+ # If installed via an omnibus installer, this gives the path to the
1271
+ # "embedded" directory which contains all of the software packaged with
1272
+ # omnibus. This is used to locate the cacert.pem file on windows.
1273
+ def self.embedded_dir
1274
+ Pathname.new(_this_file).ascend do |path|
1275
+ if path.basename.to_s == "embedded"
1276
+ return path.to_s
1277
+ end
1278
+ end
1279
+
1280
+ nil
1281
+ end
1282
+
1283
+ # Path to this file in the current install.
1284
+ def self._this_file
1285
+ File.expand_path(__FILE__)
1286
+ end
1287
+
1288
+ # Set fips mode in openssl. Do any patching necessary to make
1289
+ # sure Chef runs do not crash.
1290
+ # @api private
1291
+ def self.enable_fips_mode
1292
+ OpenSSL.fips_mode = true
1293
+ require "digest" unless defined?(Digest)
1294
+ require "digest/sha1" unless defined?(Digest::SHA1)
1295
+ require "digest/md5" unless defined?(Digest::MD5)
1296
+ # Remove pre-existing constants if they do exist to reduce the
1297
+ # amount of log spam and warnings.
1298
+ Digest.send(:remove_const, "SHA1") if Digest.const_defined?(:SHA1)
1299
+ Digest.const_set(:SHA1, OpenSSL::Digest::SHA1)
1300
+ OpenSSL::Digest.send(:remove_const, "MD5") if OpenSSL::Digest.const_defined?(:MD5)
1301
+ OpenSSL::Digest.const_set(:MD5, Digest::MD5)
1302
+ ChefConfig.logger.debug "FIPS mode is enabled."
1303
+ end
1304
+ end
1305
+ end