chef-config 18.2.5 → 18.2.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,1315 +1,1315 @@
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 we move certs into the certstore, we need to manage multi-user scenarios.
782
- # This flag is used in conjunction with 'migrate_key_to_keystore'. If 2 users, Bob and Terri, are using
783
- # this node, we need a means to separate the private keys of each user. Alternately, if an Admin
784
- # configures the node and then relies on a system account to run chef afterward, we need a second
785
- # method for that. Setting this in the client.rb file with a "user" flag will cause chef to create
786
- # and manage separate private keys. We look for this flag to be set to "user" to manage distinct users keys with,
787
- # However, if that key is set to anything else, we assume that keys are to be stored in the LocalMachine store.
788
- # Leaving this key omitted has the same effect as setting it to anything other than "user"
789
- default :auth_key_registry_type, nil
790
-
791
- # When registering the client, should we allow the client key location to
792
- # be a symlink? eg: /etc/chef/client.pem -> /etc/chef/prod-client.pem
793
- # If the path of the key goes through a directory like /tmp this should
794
- # never be set to true or its possibly an easily exploitable security hole.
795
- default :follow_client_key_symlink, false
796
-
797
- # Enable ssh-agent signing mode. This requires {client_key} be set to a
798
- # public key rather than the usual private key.
799
- default :ssh_agent_signing, false
800
-
801
- # This secret is used to decrypt encrypted data bag items.
802
- default(:encrypted_data_bag_secret) do
803
- if target_mode? && File.exist?(PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/encrypted_data_bag_secret"))
804
- PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/encrypted_data_bag_secret")
805
- elsif File.exist?(PathHelper.cleanpath("#{etc_chef_dir}/encrypted_data_bag_secret"))
806
- PathHelper.cleanpath("#{etc_chef_dir}/encrypted_data_bag_secret")
807
- else
808
- nil
809
- end
810
- end
811
-
812
- # As of Chef 13.0, version "3" is the default encrypted data bag item
813
- # format.
814
- #
815
- default :data_bag_encrypt_version, 3
816
-
817
- # When reading data bag items, any supported version is accepted. However,
818
- # if all encrypted data bags have been generated with the version 2 format,
819
- # it is recommended to disable support for earlier formats to improve
820
- # security. For example, the version 2 format is identical to version 1
821
- # except for the addition of an HMAC, so an attacker with MITM capability
822
- # could downgrade an encrypted data bag to version 1 as part of an attack.
823
- default :data_bag_decrypt_minimum_version, 0
824
-
825
- # If there is no file in the location given by `client_key`, chef-client
826
- # will temporarily use the "validator" identity to generate one. If the
827
- # `client_key` is not present and the `validation_key` is also not present,
828
- # chef-client will not be able to authenticate to the server.
829
- #
830
- # The `validation_key` is never used if the `client_key` exists.
831
- #
832
- # If chef-zero is enabled, this defaults to nil (no authentication).
833
- default(:validation_key) { chef_zero.enabled ? nil : PathHelper.cleanpath("#{etc_chef_dir}/validation.pem") }
834
- default :validation_client_name do
835
- # If the URL is set and looks like a normal Chef Server URL, extract the
836
- # org name and use that as part of the default.
837
- if chef_server_url.to_s =~ %r{/organizations/(.*)$}
838
- "#{$1}-validator"
839
- else
840
- "#{ChefUtils::Dist::Infra::SHORT}-validator"
841
- end
842
- end
843
-
844
- default :validation_key_contents, nil
845
- # When creating a new client via the validation_client account, Chef 11
846
- # servers allow the client to generate a key pair locally and send the
847
- # public key to the server. This is more secure and helps offload work from
848
- # the server, enhancing scalability. If enabled and the remote server
849
- # implements only the Chef 10 API, client registration will not work
850
- # properly.
851
- #
852
- # The default value is `true`. Set to `false` to disable client-side key
853
- # generation (server generates client keys).
854
- default(:local_key_generation) { true }
855
-
856
- # Zypper package provider gpg checks. Set to false to disable package
857
- # gpg signature checking globally. This will warn you that it is a
858
- # bad thing to do.
859
- default :zypper_check_gpg, true
860
-
861
- # Report Handlers
862
- default :report_handlers, []
863
-
864
- # Event Handlers
865
- default :event_handlers, []
866
-
867
- default :disable_event_loggers, false
868
-
869
- # Exception Handlers
870
- default :exception_handlers, []
871
-
872
- # Start handlers
873
- default :start_handlers, []
874
-
875
- # Syntax Check Cache. Knife keeps track of files that is has already syntax
876
- # checked by storing files in this directory. `syntax_check_cache_path` is
877
- # the new (and preferred) configuration setting. If not set, knife will
878
- # fall back to using cache_options[:path], which is deprecated but exists in
879
- # many client configs generated by pre-Chef-11 bootstrappers.
880
- default(:syntax_check_cache_path) { cache_options[:path] }.writes_value { |path| expand_relative_paths(path) }
881
-
882
- # Deprecated:
883
- # Move this to the default value of syntax_cache_path when this is removed.
884
- default(:cache_options) { { path: PathHelper.join(config_dir, "syntaxcache") } }
885
-
886
- # Whether errors should be raised for deprecation warnings. When set to
887
- # `false` (the default setting), a warning is emitted but code using
888
- # deprecated methods/features/etc. should work normally otherwise. When set
889
- # to `true`, usage of deprecated methods/features will raise a
890
- # `DeprecatedFeatureError`. This is used by Chef's tests to ensure that
891
- # deprecated functionality is not used internally by Chef. End users
892
- # should generally leave this at the default setting (especially in
893
- # production), but it may be useful when testing cookbooks or other code if
894
- # the user wishes to aggressively address deprecations.
895
- default(:treat_deprecation_warnings_as_errors) do
896
- # Using an environment variable allows this setting to be inherited in
897
- # tests that spawn new processes.
898
- ENV.key?("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
899
- end
900
-
901
- # Which deprecations warnings to silence. Can be set to `true` to silence
902
- # all warnings, or an array of strings like either `"deprecation_type"` or
903
- # `"filename.rb:lineno"`.
904
- default :silence_deprecation_warnings, []
905
-
906
- # Whether the resource count should be updated for log resource
907
- # on running chef-client
908
- default :count_log_resource_updates, false
909
-
910
- # The selected profile when using credentials.
911
- default :profile, nil
912
-
913
- default :chef_guid_path do
914
- PathHelper.join(config_dir, "#{ChefUtils::Dist::Infra::SHORT}_guid")
915
- end
916
-
917
- default :chef_guid, nil
918
-
919
- # knife configuration data
920
- config_context :knife do
921
- default :hints, {}
922
- end
923
-
924
- def self.set_defaults_for_windows
925
- # Those lists of regular expressions define what chef considers a
926
- # valid user and group name
927
- # From http://technet.microsoft.com/en-us/library/cc776019(WS.10).aspx
928
- principal_valid_regex_part = '[^"\/\\\\\[\]\:;|=,+*?<>]+'
929
- default :user_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
930
- default :group_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
931
-
932
- default :fatal_windows_admin_check, false
933
- end
934
-
935
- def self.set_defaults_for_nix
936
- # Those lists of regular expressions define what chef considers a
937
- # valid user and group name
938
- #
939
- # user/group cannot start with '-', '+' or '~'
940
- # user/group cannot contain ':', ',' or non-space-whitespace or null byte
941
- # everything else is allowed (UTF-8, spaces, etc) and we delegate to your O/S useradd program to barf or not
942
- # copies: http://anonscm.debian.org/viewvc/pkg-shadow/debian/trunk/debian/patches/506_relaxed_usernames?view=markup
943
- default :user_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
944
- default :group_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
945
- end
946
-
947
- # Those lists of regular expressions define what chef considers a
948
- # valid user and group name
949
- if ChefUtils.windows?
950
- set_defaults_for_windows
951
- else
952
- set_defaults_for_nix
953
- end
954
-
955
- # This provides a hook which rspec can stub so that we can avoid twiddling
956
- # global state in tests.
957
- def self.env
958
- ENV
959
- end
960
-
961
- def self.windows_home_path
962
- ChefConfig.logger.deprecation("Chef::Config.windows_home_path is now deprecated. Consider using Chef::Util::PathHelper.home instead.")
963
- PathHelper.home
964
- end
965
-
966
- # returns a platform specific path to the user home dir if set, otherwise default to current directory.
967
- default( :user_home ) { PathHelper.home || Dir.pwd }
968
-
969
- # Enable file permission fixup for selinux. Fixup will be done
970
- # only if selinux is enabled in the system.
971
- default :enable_selinux_file_permission_fixup, true
972
-
973
- # Use atomic updates (i.e. move operation) while updating contents
974
- # of the files resources. When set to false copy operation is
975
- # used to update files.
976
- #
977
- # NOTE: CHANGING THIS SETTING MAY CAUSE CORRUPTION, DATA LOSS AND
978
- # INSTABILITY.
979
- #
980
- default :file_atomic_update, true
981
-
982
- # There are 3 possible values for this configuration setting.
983
- # true => file staging is done in the destination directory
984
- # false => file staging is done via tempfiles under ENV['TMP']
985
- # :auto => file staging will try using destination directory if possible and
986
- # will fall back to ENV['TMP'] if destination directory is not usable.
987
- #
988
- default :file_staging_uses_destdir, :auto
989
-
990
- # Exit if another run is in progress and the chef-client is unable to
991
- # get the lock before time expires. If nil, no timeout is enforced. (Exits
992
- # immediately if 0.)
993
- #
994
- default :run_lock_timeout, nil
995
-
996
- # Number of worker threads for syncing cookbooks in parallel. Increasing
997
- # this number can result in gateway errors from the server (namely 503 and 504).
998
- # If you are seeing this behavior while using the default setting, reducing
999
- # the number of threads will help.
1000
- #
1001
- default :cookbook_sync_threads, 10
1002
-
1003
- # True if all resources by default default to unified mode, with all resources
1004
- # applying in "compile" mode, with no "converge" mode. False is backwards compatible
1005
- # setting for Chef 11-15 behavior. This will break forward notifications.
1006
- #
1007
- default :resource_unified_mode_default, true
1008
-
1009
- # At the beginning of the Chef Client run, the cookbook manifests are downloaded which
1010
- # contain URLs for every file in every relevant cookbook. Most of the files
1011
- # (recipes, resources, providers, libraries, etc) are immediately synchronized
1012
- # at the start of the run. The handling of "files" and "templates" directories,
1013
- # however, have two modes of operation. They can either all be downloaded immediately
1014
- # at the start of the run (no_lazy_load==true) or else they can be lazily loaded as
1015
- # cookbook_file or template resources are converged which require them (no_lazy_load==false).
1016
- #
1017
- # The advantage of lazily loading these files is that unnecessary files are not
1018
- # synchronized. This may be useful to users with large files checked into cookbooks which
1019
- # are only selectively downloaded to a subset of clients which use the cookbook. However,
1020
- # better solutions are to either isolate large files into individual cookbooks and only
1021
- # include those cookbooks in the run lists of the servers that need them -- or move to
1022
- # using remote_file and a more appropriate backing store like S3 for large file
1023
- # distribution.
1024
- #
1025
- # The disadvantages of lazily loading files are that users some time find it
1026
- # confusing that their cookbooks are not fully synchronized to the cache initially,
1027
- # and more importantly the time-sensitive URLs which are in the manifest may time
1028
- # out on long Chef runs before the resource that uses the file is converged
1029
- # (leading to many confusing 403 errors on template/cookbook_file resources).
1030
- #
1031
- default :no_lazy_load, true
1032
-
1033
- # A array of attributes you want sent over the wire when node
1034
- # data is saved. The default setting is nil, which collects all data.
1035
- # NOTE: Setting to [] will not collect ANY data to save.
1036
- default :allowed_automatic_attributes, nil
1037
- default :allowed_default_attributes, nil
1038
- default :allowed_normal_attributes, nil
1039
- default :allowed_override_attributes, nil
1040
-
1041
- # An array of attributes you do not want to send over the
1042
- # wire when node data is saved
1043
- # The default setting is nil, which collects all data.
1044
- # NOTE: Setting to [] will still collect all data to save
1045
- default :blocked_automatic_attributes, nil
1046
- default :blocked_default_attributes, nil
1047
- default :blocked_normal_attributes, nil
1048
- default :blocked_override_attributes, nil
1049
-
1050
- # deprecated config options that will be removed in Chef Infra Client 18
1051
- default :automatic_attribute_blacklist, nil
1052
- default :default_attribute_blacklist, nil
1053
- default :normal_attribute_blacklist, nil
1054
- default :override_attribute_blacklist, nil
1055
- default :automatic_attribute_whitelist, nil
1056
- default :default_attribute_whitelist, nil
1057
- default :normal_attribute_whitelist, nil
1058
- default :override_attribute_whitelist, nil
1059
-
1060
- # Pull down all the rubygems versions from rubygems and cache them the first time we do a gem_package or
1061
- # chef_gem install. This is memory-expensive and will grow without bounds, but will reduce network
1062
- # round trips.
1063
- default :rubygems_cache_enabled, false
1064
-
1065
- config_context :windows_service do
1066
- # Set `watchdog_timeout` to the number of seconds to wait for a chef-client run
1067
- # to finish
1068
- default :watchdog_timeout, 2 * (60 * 60) # 2 hours
1069
- end
1070
-
1071
- # Add an empty and non-strict config_context for chefdk and chefcli.
1072
- # This lets the user have code like `chefdk.generator_cookbook "/path/to/cookbook"` or
1073
- # `chefcli[:generator_cookbook] = "/path/to/cookbook"` in their config.rb,
1074
- # and it will be ignored by tools like knife and ohai. ChefDK and ChefCLI
1075
- # themselves can define the config options it accepts and enable strict mode,
1076
- # and that will only apply when running `chef` commands.
1077
- config_context :chefdk do
1078
- end
1079
-
1080
- config_context :chefcli do
1081
- end
1082
-
1083
- # Configuration options for Data Collector reporting. These settings allow
1084
- # the user to configure where to send their Data Collector data, what token
1085
- # to send, and whether Data Collector should report its findings in client
1086
- # mode vs. solo mode.
1087
- config_context :data_collector do
1088
- # Full URL to the endpoint that will receive our data. If nil, the
1089
- # data collector will not run.
1090
- # Ex: http://my-data-collector.mycompany.com/ingest
1091
- default(:server_url) do
1092
- if config_parent.solo_legacy_mode || config_parent.local_mode
1093
- nil
1094
- else
1095
- File.join(config_parent.chef_server_url, "/data-collector")
1096
- end
1097
- end
1098
-
1099
- # An optional pre-shared token to pass as an HTTP header (x-data-collector-token)
1100
- # that can be used to determine whether or not the poster of this
1101
- # run data should be trusted.
1102
- # Ex: some-uuid-here
1103
- default :token, nil
1104
-
1105
- # The Chef mode during which Data Collector is allowed to function. This
1106
- # can be used to run Data Collector only when running as Chef Solo but
1107
- # not when using Chef Client.
1108
- # Options: :solo (for both Solo Legacy Mode and Client Local Mode), :client, :both
1109
- default :mode, :both
1110
-
1111
- # When the Data Collector cannot send the "starting a run" message to
1112
- # the Data Collector server, the Data Collector will be disabled for that
1113
- # run. In some situations, such as highly-regulated environments, it
1114
- # may be more reasonable to prevent Chef from performing the actual run.
1115
- # In these situations, setting this value to true will cause the Chef
1116
- # run to raise an exception before starting any converge activities.
1117
- default :raise_on_failure, false
1118
-
1119
- # A user-supplied Organization string that can be sent in payloads
1120
- # generated by the DataCollector when Chef is run in Solo mode. This
1121
- # allows users to associate their Solo nodes with faux organizations
1122
- # without the nodes being connected to an actual Chef Server.
1123
- default :organization, "#{ChefUtils::Dist::Infra::SHORT}_solo"
1124
- end
1125
-
1126
- configurable(:http_proxy)
1127
- configurable(:http_proxy_user)
1128
- configurable(:http_proxy_pass)
1129
- configurable(:https_proxy)
1130
- configurable(:https_proxy_user)
1131
- configurable(:https_proxy_pass)
1132
- configurable(:ftp_proxy)
1133
- configurable(:ftp_proxy_user)
1134
- configurable(:ftp_proxy_pass)
1135
- configurable(:no_proxy)
1136
-
1137
- # Public method that users should call to export proxies to the appropriate
1138
- # environment variables. This method should be called after the config file is
1139
- # parsed and loaded.
1140
- # TODO add some post-file-parsing logic that automatically calls this so
1141
- # users don't have to
1142
- def self.export_proxies
1143
- export_proxy("http", http_proxy, http_proxy_user, http_proxy_pass) if key?(:http_proxy) && http_proxy
1144
- export_proxy("https", https_proxy, https_proxy_user, https_proxy_pass) if key?(:https_proxy) && https_proxy
1145
- export_proxy("ftp", ftp_proxy, ftp_proxy_user, ftp_proxy_pass) if key?(:ftp_proxy) && ftp_proxy
1146
- export_no_proxy(no_proxy) if key?(:no_proxy) && no_proxy
1147
- end
1148
-
1149
- # Builds a proxy uri and exports it to the appropriate environment variables. Examples:
1150
- # http://username:password@hostname:port
1151
- # https://username@hostname:port
1152
- # ftp://hostname:port
1153
- # when
1154
- # scheme = "http", "https", or "ftp"
1155
- # hostport = hostname:port or scheme://hostname:port
1156
- # user = username
1157
- # pass = password
1158
- # @api private
1159
- def self.export_proxy(scheme, path, user, pass)
1160
- # Character classes for Addressable
1161
- # See https://www.ietf.org/rfc/rfc3986.txt 3.2.1
1162
- # The user part may not have a : in it
1163
- user_class = Addressable::URI::CharacterClasses::UNRESERVED + Addressable::URI::CharacterClasses::SUB_DELIMS
1164
- # The password part may have any valid USERINFO characters
1165
- password_class = user_class + "\\:"
1166
-
1167
- path = "#{scheme}://#{path}" unless path.include?("://")
1168
- # URI.split returns the following parts:
1169
- # [scheme, userinfo, host, port, registry, path, opaque, query, fragment]
1170
- uri = Addressable::URI.encode(path, Addressable::URI)
1171
-
1172
- if user && !user.empty?
1173
- userinfo = Addressable::URI.encode_component(user, user_class)
1174
- if pass
1175
- userinfo << ":#{Addressable::URI.encode_component(pass, password_class)}"
1176
- end
1177
- uri.userinfo = userinfo
1178
- end
1179
-
1180
- path = uri.to_s
1181
- ENV["#{scheme}_proxy".downcase] = path unless ENV["#{scheme}_proxy".downcase]
1182
- ENV["#{scheme}_proxy".upcase] = path unless ENV["#{scheme}_proxy".upcase]
1183
- end
1184
-
1185
- # @api private
1186
- def self.export_no_proxy(value)
1187
- ENV["no_proxy"] = value unless ENV["no_proxy"]
1188
- ENV["NO_PROXY"] = value unless ENV["NO_PROXY"]
1189
- end
1190
-
1191
- # Given a scheme, host, and port, return the correct proxy URI based on the
1192
- # set environment variables, unless excluded by no_proxy, in which case nil
1193
- # is returned
1194
- def self.proxy_uri(scheme, host, port)
1195
- proxy_env_var = ENV["#{scheme}_proxy"].to_s.strip
1196
-
1197
- # Check if the proxy string contains a scheme. If not, add the url's scheme to the
1198
- # proxy before parsing. The regex /^.*:\/\// matches, for example, http://. Reusing proxy
1199
- # here since we are really just trying to get the string built correctly.
1200
- proxy = unless proxy_env_var.empty?
1201
- if %r{^.*://}.match?(proxy_env_var)
1202
- URI.parse(proxy_env_var)
1203
- else
1204
- URI.parse("#{scheme}://#{proxy_env_var}")
1205
- end
1206
- end
1207
-
1208
- return proxy unless fuzzy_hostname_match_any?(host, ENV["no_proxy"])
1209
- end
1210
-
1211
- # Chef requires an English-language UTF-8 locale to function properly. We attempt
1212
- # to use the 'locale -a' command and search through a list of preferences until we
1213
- # find one that we can use. On Ubuntu systems we should find 'C.UTF-8' and be
1214
- # able to use that even if there is no English locale on the server, but Mac, Solaris,
1215
- # AIX, etc do not have that locale. We then try to find an English locale and fall
1216
- # back to 'C' if we do not. The choice of fallback is pick-your-poison. If we try
1217
- # to do the work to return a non-US UTF-8 locale then we fail inside of providers when
1218
- # things like 'svn info' return Japanese and we can't parse them. OTOH, if we pick 'C' then
1219
- # we will blow up on UTF-8 characters. Between the warn we throw and the Encoding
1220
- # exception that ruby will throw it is more obvious what is broken if we drop UTF-8 by
1221
- # default rather than drop English.
1222
- #
1223
- # If there is no 'locale -a' then we return 'en_US.UTF-8' since that is the most commonly
1224
- # available English UTF-8 locale. However, all modern POSIXen should support 'locale -a'.
1225
- def self.guess_internal_locale
1226
- # https://github.com/chef/chef/issues/2181
1227
- # Some systems have the `locale -a` command, but the result has
1228
- # invalid characters for the default encoding.
1229
- #
1230
- # For example, on CentOS 6 with ENV['LANG'] = "en_US.UTF-8",
1231
- # `locale -a`.split fails with ArgumentError invalid UTF-8 encoding.
1232
- cmd = Mixlib::ShellOut.new("locale -a").run_command
1233
- cmd.error!
1234
- locales = cmd.stdout.split
1235
- case
1236
- when locales.include?("C.UTF-8")
1237
- "C.UTF-8"
1238
- when locales.include?("en_US.UTF-8"), locales.include?("en_US.utf8")
1239
- "en_US.UTF-8"
1240
- when locales.include?("en.UTF-8")
1241
- "en.UTF-8"
1242
- else
1243
- # Will match en_ZZ.UTF-8, en_ZZ.utf-8, en_ZZ.UTF8, en_ZZ.utf8
1244
- guesses = locales.grep(/^en_.*UTF-?8$/i)
1245
- unless guesses.empty?
1246
- guessed_locale = guesses.first
1247
- # Transform into the form en_ZZ.UTF-8
1248
- guessed_locale.gsub(/UTF-?8$/i, "UTF-8")
1249
- else
1250
- 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."
1251
- "C"
1252
- end
1253
- end
1254
- rescue
1255
- if ChefUtils.windows?
1256
- ChefConfig.logger.trace "Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else."
1257
- else
1258
- ChefConfig.logger.trace "No usable locale -a command found, assuming you have en_US.UTF-8 installed."
1259
- end
1260
- "en_US.UTF-8"
1261
- end
1262
-
1263
- default :internal_locale, guess_internal_locale
1264
-
1265
- # Force UTF-8 Encoding, for when we fire up in the 'C' locale or other strange locales (e.g.
1266
- # japanese windows encodings). If we do not do this, then knife upload will fail when a cookbook's
1267
- # README.md has UTF-8 characters that do not encode in whatever surrounding encoding we have been
1268
- # passed. Effectively, the Chef Ecosystem is globally UTF-8 by default. Anyone who wants to be
1269
- # able to upload Shift_JIS or ISO-8859-1 files needs to mark *those* files explicitly with
1270
- # magic tags to make ruby correctly identify the encoding being used. Changing this default will
1271
- # break Chef community cookbooks and is very highly discouraged.
1272
- default :ruby_encoding, Encoding::UTF_8
1273
-
1274
- # can be set to a string or array of strings for URIs to set as rubygems sources
1275
- default :rubygems_url, nil
1276
-
1277
- # globally sets the default of the clear_sources property on the gem_package and chef_gem resources
1278
- default :clear_gem_sources, nil
1279
-
1280
- # If installed via an omnibus installer, this gives the path to the
1281
- # "embedded" directory which contains all of the software packaged with
1282
- # omnibus. This is used to locate the cacert.pem file on windows.
1283
- def self.embedded_dir
1284
- Pathname.new(_this_file).ascend do |path|
1285
- if path.basename.to_s == "embedded"
1286
- return path.to_s
1287
- end
1288
- end
1289
-
1290
- nil
1291
- end
1292
-
1293
- # Path to this file in the current install.
1294
- def self._this_file
1295
- File.expand_path(__FILE__)
1296
- end
1297
-
1298
- # Set fips mode in openssl. Do any patching necessary to make
1299
- # sure Chef runs do not crash.
1300
- # @api private
1301
- def self.enable_fips_mode
1302
- OpenSSL.fips_mode = true
1303
- require "digest" unless defined?(Digest)
1304
- require "digest/sha1" unless defined?(Digest::SHA1)
1305
- require "digest/md5" unless defined?(Digest::MD5)
1306
- # Remove pre-existing constants if they do exist to reduce the
1307
- # amount of log spam and warnings.
1308
- Digest.send(:remove_const, "SHA1") if Digest.const_defined?(:SHA1)
1309
- Digest.const_set(:SHA1, OpenSSL::Digest::SHA1)
1310
- OpenSSL::Digest.send(:remove_const, "MD5") if OpenSSL::Digest.const_defined?(:MD5)
1311
- OpenSSL::Digest.const_set(:MD5, Digest::MD5)
1312
- ChefConfig.logger.debug "FIPS mode is enabled."
1313
- end
1314
- end
1315
- 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 we move certs into the certstore, we need to manage multi-user scenarios.
782
+ # This flag is used in conjunction with 'migrate_key_to_keystore'. If 2 users, Bob and Terri, are using
783
+ # this node, we need a means to separate the private keys of each user. Alternately, if an Admin
784
+ # configures the node and then relies on a system account to run chef afterward, we need a second
785
+ # method for that. Setting this in the client.rb file with a "user" flag will cause chef to create
786
+ # and manage separate private keys. We look for this flag to be set to "user" to manage distinct users keys with,
787
+ # However, if that key is set to anything else, we assume that keys are to be stored in the LocalMachine store.
788
+ # Leaving this key omitted has the same effect as setting it to anything other than "user"
789
+ default :auth_key_registry_type, nil
790
+
791
+ # When registering the client, should we allow the client key location to
792
+ # be a symlink? eg: /etc/chef/client.pem -> /etc/chef/prod-client.pem
793
+ # If the path of the key goes through a directory like /tmp this should
794
+ # never be set to true or its possibly an easily exploitable security hole.
795
+ default :follow_client_key_symlink, false
796
+
797
+ # Enable ssh-agent signing mode. This requires {client_key} be set to a
798
+ # public key rather than the usual private key.
799
+ default :ssh_agent_signing, false
800
+
801
+ # This secret is used to decrypt encrypted data bag items.
802
+ default(:encrypted_data_bag_secret) do
803
+ if target_mode? && File.exist?(PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/encrypted_data_bag_secret"))
804
+ PathHelper.cleanpath("#{etc_chef_dir}/#{target_mode.host}/encrypted_data_bag_secret")
805
+ elsif File.exist?(PathHelper.cleanpath("#{etc_chef_dir}/encrypted_data_bag_secret"))
806
+ PathHelper.cleanpath("#{etc_chef_dir}/encrypted_data_bag_secret")
807
+ else
808
+ nil
809
+ end
810
+ end
811
+
812
+ # As of Chef 13.0, version "3" is the default encrypted data bag item
813
+ # format.
814
+ #
815
+ default :data_bag_encrypt_version, 3
816
+
817
+ # When reading data bag items, any supported version is accepted. However,
818
+ # if all encrypted data bags have been generated with the version 2 format,
819
+ # it is recommended to disable support for earlier formats to improve
820
+ # security. For example, the version 2 format is identical to version 1
821
+ # except for the addition of an HMAC, so an attacker with MITM capability
822
+ # could downgrade an encrypted data bag to version 1 as part of an attack.
823
+ default :data_bag_decrypt_minimum_version, 0
824
+
825
+ # If there is no file in the location given by `client_key`, chef-client
826
+ # will temporarily use the "validator" identity to generate one. If the
827
+ # `client_key` is not present and the `validation_key` is also not present,
828
+ # chef-client will not be able to authenticate to the server.
829
+ #
830
+ # The `validation_key` is never used if the `client_key` exists.
831
+ #
832
+ # If chef-zero is enabled, this defaults to nil (no authentication).
833
+ default(:validation_key) { chef_zero.enabled ? nil : PathHelper.cleanpath("#{etc_chef_dir}/validation.pem") }
834
+ default :validation_client_name do
835
+ # If the URL is set and looks like a normal Chef Server URL, extract the
836
+ # org name and use that as part of the default.
837
+ if chef_server_url.to_s =~ %r{/organizations/(.*)$}
838
+ "#{$1}-validator"
839
+ else
840
+ "#{ChefUtils::Dist::Infra::SHORT}-validator"
841
+ end
842
+ end
843
+
844
+ default :validation_key_contents, nil
845
+ # When creating a new client via the validation_client account, Chef 11
846
+ # servers allow the client to generate a key pair locally and send the
847
+ # public key to the server. This is more secure and helps offload work from
848
+ # the server, enhancing scalability. If enabled and the remote server
849
+ # implements only the Chef 10 API, client registration will not work
850
+ # properly.
851
+ #
852
+ # The default value is `true`. Set to `false` to disable client-side key
853
+ # generation (server generates client keys).
854
+ default(:local_key_generation) { true }
855
+
856
+ # Zypper package provider gpg checks. Set to false to disable package
857
+ # gpg signature checking globally. This will warn you that it is a
858
+ # bad thing to do.
859
+ default :zypper_check_gpg, true
860
+
861
+ # Report Handlers
862
+ default :report_handlers, []
863
+
864
+ # Event Handlers
865
+ default :event_handlers, []
866
+
867
+ default :disable_event_loggers, false
868
+
869
+ # Exception Handlers
870
+ default :exception_handlers, []
871
+
872
+ # Start handlers
873
+ default :start_handlers, []
874
+
875
+ # Syntax Check Cache. Knife keeps track of files that is has already syntax
876
+ # checked by storing files in this directory. `syntax_check_cache_path` is
877
+ # the new (and preferred) configuration setting. If not set, knife will
878
+ # fall back to using cache_options[:path], which is deprecated but exists in
879
+ # many client configs generated by pre-Chef-11 bootstrappers.
880
+ default(:syntax_check_cache_path) { cache_options[:path] }.writes_value { |path| expand_relative_paths(path) }
881
+
882
+ # Deprecated:
883
+ # Move this to the default value of syntax_cache_path when this is removed.
884
+ default(:cache_options) { { path: PathHelper.join(config_dir, "syntaxcache") } }
885
+
886
+ # Whether errors should be raised for deprecation warnings. When set to
887
+ # `false` (the default setting), a warning is emitted but code using
888
+ # deprecated methods/features/etc. should work normally otherwise. When set
889
+ # to `true`, usage of deprecated methods/features will raise a
890
+ # `DeprecatedFeatureError`. This is used by Chef's tests to ensure that
891
+ # deprecated functionality is not used internally by Chef. End users
892
+ # should generally leave this at the default setting (especially in
893
+ # production), but it may be useful when testing cookbooks or other code if
894
+ # the user wishes to aggressively address deprecations.
895
+ default(:treat_deprecation_warnings_as_errors) do
896
+ # Using an environment variable allows this setting to be inherited in
897
+ # tests that spawn new processes.
898
+ ENV.key?("CHEF_TREAT_DEPRECATION_WARNINGS_AS_ERRORS")
899
+ end
900
+
901
+ # Which deprecations warnings to silence. Can be set to `true` to silence
902
+ # all warnings, or an array of strings like either `"deprecation_type"` or
903
+ # `"filename.rb:lineno"`.
904
+ default :silence_deprecation_warnings, []
905
+
906
+ # Whether the resource count should be updated for log resource
907
+ # on running chef-client
908
+ default :count_log_resource_updates, false
909
+
910
+ # The selected profile when using credentials.
911
+ default :profile, nil
912
+
913
+ default :chef_guid_path do
914
+ PathHelper.join(config_dir, "#{ChefUtils::Dist::Infra::SHORT}_guid")
915
+ end
916
+
917
+ default :chef_guid, nil
918
+
919
+ # knife configuration data
920
+ config_context :knife do
921
+ default :hints, {}
922
+ end
923
+
924
+ def self.set_defaults_for_windows
925
+ # Those lists of regular expressions define what chef considers a
926
+ # valid user and group name
927
+ # From http://technet.microsoft.com/en-us/library/cc776019(WS.10).aspx
928
+ principal_valid_regex_part = '[^"\/\\\\\[\]\:;|=,+*?<>]+'
929
+ default :user_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
930
+ default :group_valid_regex, [ /^(#{principal_valid_regex_part}\\)?#{principal_valid_regex_part}$/ ]
931
+
932
+ default :fatal_windows_admin_check, false
933
+ end
934
+
935
+ def self.set_defaults_for_nix
936
+ # Those lists of regular expressions define what chef considers a
937
+ # valid user and group name
938
+ #
939
+ # user/group cannot start with '-', '+' or '~'
940
+ # user/group cannot contain ':', ',' or non-space-whitespace or null byte
941
+ # everything else is allowed (UTF-8, spaces, etc) and we delegate to your O/S useradd program to barf or not
942
+ # copies: http://anonscm.debian.org/viewvc/pkg-shadow/debian/trunk/debian/patches/506_relaxed_usernames?view=markup
943
+ default :user_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
944
+ default :group_valid_regex, [ /^[^-+~:,\t\r\n\f\0]+[^:,\t\r\n\f\0]*$/ ]
945
+ end
946
+
947
+ # Those lists of regular expressions define what chef considers a
948
+ # valid user and group name
949
+ if ChefUtils.windows?
950
+ set_defaults_for_windows
951
+ else
952
+ set_defaults_for_nix
953
+ end
954
+
955
+ # This provides a hook which rspec can stub so that we can avoid twiddling
956
+ # global state in tests.
957
+ def self.env
958
+ ENV
959
+ end
960
+
961
+ def self.windows_home_path
962
+ ChefConfig.logger.deprecation("Chef::Config.windows_home_path is now deprecated. Consider using Chef::Util::PathHelper.home instead.")
963
+ PathHelper.home
964
+ end
965
+
966
+ # returns a platform specific path to the user home dir if set, otherwise default to current directory.
967
+ default( :user_home ) { PathHelper.home || Dir.pwd }
968
+
969
+ # Enable file permission fixup for selinux. Fixup will be done
970
+ # only if selinux is enabled in the system.
971
+ default :enable_selinux_file_permission_fixup, true
972
+
973
+ # Use atomic updates (i.e. move operation) while updating contents
974
+ # of the files resources. When set to false copy operation is
975
+ # used to update files.
976
+ #
977
+ # NOTE: CHANGING THIS SETTING MAY CAUSE CORRUPTION, DATA LOSS AND
978
+ # INSTABILITY.
979
+ #
980
+ default :file_atomic_update, true
981
+
982
+ # There are 3 possible values for this configuration setting.
983
+ # true => file staging is done in the destination directory
984
+ # false => file staging is done via tempfiles under ENV['TMP']
985
+ # :auto => file staging will try using destination directory if possible and
986
+ # will fall back to ENV['TMP'] if destination directory is not usable.
987
+ #
988
+ default :file_staging_uses_destdir, :auto
989
+
990
+ # Exit if another run is in progress and the chef-client is unable to
991
+ # get the lock before time expires. If nil, no timeout is enforced. (Exits
992
+ # immediately if 0.)
993
+ #
994
+ default :run_lock_timeout, nil
995
+
996
+ # Number of worker threads for syncing cookbooks in parallel. Increasing
997
+ # this number can result in gateway errors from the server (namely 503 and 504).
998
+ # If you are seeing this behavior while using the default setting, reducing
999
+ # the number of threads will help.
1000
+ #
1001
+ default :cookbook_sync_threads, 10
1002
+
1003
+ # True if all resources by default default to unified mode, with all resources
1004
+ # applying in "compile" mode, with no "converge" mode. False is backwards compatible
1005
+ # setting for Chef 11-15 behavior. This will break forward notifications.
1006
+ #
1007
+ default :resource_unified_mode_default, true
1008
+
1009
+ # At the beginning of the Chef Client run, the cookbook manifests are downloaded which
1010
+ # contain URLs for every file in every relevant cookbook. Most of the files
1011
+ # (recipes, resources, providers, libraries, etc) are immediately synchronized
1012
+ # at the start of the run. The handling of "files" and "templates" directories,
1013
+ # however, have two modes of operation. They can either all be downloaded immediately
1014
+ # at the start of the run (no_lazy_load==true) or else they can be lazily loaded as
1015
+ # cookbook_file or template resources are converged which require them (no_lazy_load==false).
1016
+ #
1017
+ # The advantage of lazily loading these files is that unnecessary files are not
1018
+ # synchronized. This may be useful to users with large files checked into cookbooks which
1019
+ # are only selectively downloaded to a subset of clients which use the cookbook. However,
1020
+ # better solutions are to either isolate large files into individual cookbooks and only
1021
+ # include those cookbooks in the run lists of the servers that need them -- or move to
1022
+ # using remote_file and a more appropriate backing store like S3 for large file
1023
+ # distribution.
1024
+ #
1025
+ # The disadvantages of lazily loading files are that users some time find it
1026
+ # confusing that their cookbooks are not fully synchronized to the cache initially,
1027
+ # and more importantly the time-sensitive URLs which are in the manifest may time
1028
+ # out on long Chef runs before the resource that uses the file is converged
1029
+ # (leading to many confusing 403 errors on template/cookbook_file resources).
1030
+ #
1031
+ default :no_lazy_load, true
1032
+
1033
+ # A array of attributes you want sent over the wire when node
1034
+ # data is saved. The default setting is nil, which collects all data.
1035
+ # NOTE: Setting to [] will not collect ANY data to save.
1036
+ default :allowed_automatic_attributes, nil
1037
+ default :allowed_default_attributes, nil
1038
+ default :allowed_normal_attributes, nil
1039
+ default :allowed_override_attributes, nil
1040
+
1041
+ # An array of attributes you do not want to send over the
1042
+ # wire when node data is saved
1043
+ # The default setting is nil, which collects all data.
1044
+ # NOTE: Setting to [] will still collect all data to save
1045
+ default :blocked_automatic_attributes, nil
1046
+ default :blocked_default_attributes, nil
1047
+ default :blocked_normal_attributes, nil
1048
+ default :blocked_override_attributes, nil
1049
+
1050
+ # deprecated config options that will be removed in Chef Infra Client 18
1051
+ default :automatic_attribute_blacklist, nil
1052
+ default :default_attribute_blacklist, nil
1053
+ default :normal_attribute_blacklist, nil
1054
+ default :override_attribute_blacklist, nil
1055
+ default :automatic_attribute_whitelist, nil
1056
+ default :default_attribute_whitelist, nil
1057
+ default :normal_attribute_whitelist, nil
1058
+ default :override_attribute_whitelist, nil
1059
+
1060
+ # Pull down all the rubygems versions from rubygems and cache them the first time we do a gem_package or
1061
+ # chef_gem install. This is memory-expensive and will grow without bounds, but will reduce network
1062
+ # round trips.
1063
+ default :rubygems_cache_enabled, false
1064
+
1065
+ config_context :windows_service do
1066
+ # Set `watchdog_timeout` to the number of seconds to wait for a chef-client run
1067
+ # to finish
1068
+ default :watchdog_timeout, 2 * (60 * 60) # 2 hours
1069
+ end
1070
+
1071
+ # Add an empty and non-strict config_context for chefdk and chefcli.
1072
+ # This lets the user have code like `chefdk.generator_cookbook "/path/to/cookbook"` or
1073
+ # `chefcli[:generator_cookbook] = "/path/to/cookbook"` in their config.rb,
1074
+ # and it will be ignored by tools like knife and ohai. ChefDK and ChefCLI
1075
+ # themselves can define the config options it accepts and enable strict mode,
1076
+ # and that will only apply when running `chef` commands.
1077
+ config_context :chefdk do
1078
+ end
1079
+
1080
+ config_context :chefcli do
1081
+ end
1082
+
1083
+ # Configuration options for Data Collector reporting. These settings allow
1084
+ # the user to configure where to send their Data Collector data, what token
1085
+ # to send, and whether Data Collector should report its findings in client
1086
+ # mode vs. solo mode.
1087
+ config_context :data_collector do
1088
+ # Full URL to the endpoint that will receive our data. If nil, the
1089
+ # data collector will not run.
1090
+ # Ex: http://my-data-collector.mycompany.com/ingest
1091
+ default(:server_url) do
1092
+ if config_parent.solo_legacy_mode || config_parent.local_mode
1093
+ nil
1094
+ else
1095
+ File.join(config_parent.chef_server_url, "/data-collector")
1096
+ end
1097
+ end
1098
+
1099
+ # An optional pre-shared token to pass as an HTTP header (x-data-collector-token)
1100
+ # that can be used to determine whether or not the poster of this
1101
+ # run data should be trusted.
1102
+ # Ex: some-uuid-here
1103
+ default :token, nil
1104
+
1105
+ # The Chef mode during which Data Collector is allowed to function. This
1106
+ # can be used to run Data Collector only when running as Chef Solo but
1107
+ # not when using Chef Client.
1108
+ # Options: :solo (for both Solo Legacy Mode and Client Local Mode), :client, :both
1109
+ default :mode, :both
1110
+
1111
+ # When the Data Collector cannot send the "starting a run" message to
1112
+ # the Data Collector server, the Data Collector will be disabled for that
1113
+ # run. In some situations, such as highly-regulated environments, it
1114
+ # may be more reasonable to prevent Chef from performing the actual run.
1115
+ # In these situations, setting this value to true will cause the Chef
1116
+ # run to raise an exception before starting any converge activities.
1117
+ default :raise_on_failure, false
1118
+
1119
+ # A user-supplied Organization string that can be sent in payloads
1120
+ # generated by the DataCollector when Chef is run in Solo mode. This
1121
+ # allows users to associate their Solo nodes with faux organizations
1122
+ # without the nodes being connected to an actual Chef Server.
1123
+ default :organization, "#{ChefUtils::Dist::Infra::SHORT}_solo"
1124
+ end
1125
+
1126
+ configurable(:http_proxy)
1127
+ configurable(:http_proxy_user)
1128
+ configurable(:http_proxy_pass)
1129
+ configurable(:https_proxy)
1130
+ configurable(:https_proxy_user)
1131
+ configurable(:https_proxy_pass)
1132
+ configurable(:ftp_proxy)
1133
+ configurable(:ftp_proxy_user)
1134
+ configurable(:ftp_proxy_pass)
1135
+ configurable(:no_proxy)
1136
+
1137
+ # Public method that users should call to export proxies to the appropriate
1138
+ # environment variables. This method should be called after the config file is
1139
+ # parsed and loaded.
1140
+ # TODO add some post-file-parsing logic that automatically calls this so
1141
+ # users don't have to
1142
+ def self.export_proxies
1143
+ export_proxy("http", http_proxy, http_proxy_user, http_proxy_pass) if key?(:http_proxy) && http_proxy
1144
+ export_proxy("https", https_proxy, https_proxy_user, https_proxy_pass) if key?(:https_proxy) && https_proxy
1145
+ export_proxy("ftp", ftp_proxy, ftp_proxy_user, ftp_proxy_pass) if key?(:ftp_proxy) && ftp_proxy
1146
+ export_no_proxy(no_proxy) if key?(:no_proxy) && no_proxy
1147
+ end
1148
+
1149
+ # Builds a proxy uri and exports it to the appropriate environment variables. Examples:
1150
+ # http://username:password@hostname:port
1151
+ # https://username@hostname:port
1152
+ # ftp://hostname:port
1153
+ # when
1154
+ # scheme = "http", "https", or "ftp"
1155
+ # hostport = hostname:port or scheme://hostname:port
1156
+ # user = username
1157
+ # pass = password
1158
+ # @api private
1159
+ def self.export_proxy(scheme, path, user, pass)
1160
+ # Character classes for Addressable
1161
+ # See https://www.ietf.org/rfc/rfc3986.txt 3.2.1
1162
+ # The user part may not have a : in it
1163
+ user_class = Addressable::URI::CharacterClasses::UNRESERVED + Addressable::URI::CharacterClasses::SUB_DELIMS
1164
+ # The password part may have any valid USERINFO characters
1165
+ password_class = user_class + "\\:"
1166
+
1167
+ path = "#{scheme}://#{path}" unless path.include?("://")
1168
+ # URI.split returns the following parts:
1169
+ # [scheme, userinfo, host, port, registry, path, opaque, query, fragment]
1170
+ uri = Addressable::URI.encode(path, Addressable::URI)
1171
+
1172
+ if user && !user.empty?
1173
+ userinfo = Addressable::URI.encode_component(user, user_class)
1174
+ if pass
1175
+ userinfo << ":#{Addressable::URI.encode_component(pass, password_class)}"
1176
+ end
1177
+ uri.userinfo = userinfo
1178
+ end
1179
+
1180
+ path = uri.to_s
1181
+ ENV["#{scheme}_proxy".downcase] = path unless ENV["#{scheme}_proxy".downcase]
1182
+ ENV["#{scheme}_proxy".upcase] = path unless ENV["#{scheme}_proxy".upcase]
1183
+ end
1184
+
1185
+ # @api private
1186
+ def self.export_no_proxy(value)
1187
+ ENV["no_proxy"] = value unless ENV["no_proxy"]
1188
+ ENV["NO_PROXY"] = value unless ENV["NO_PROXY"]
1189
+ end
1190
+
1191
+ # Given a scheme, host, and port, return the correct proxy URI based on the
1192
+ # set environment variables, unless excluded by no_proxy, in which case nil
1193
+ # is returned
1194
+ def self.proxy_uri(scheme, host, port)
1195
+ proxy_env_var = ENV["#{scheme}_proxy"].to_s.strip
1196
+
1197
+ # Check if the proxy string contains a scheme. If not, add the url's scheme to the
1198
+ # proxy before parsing. The regex /^.*:\/\// matches, for example, http://. Reusing proxy
1199
+ # here since we are really just trying to get the string built correctly.
1200
+ proxy = unless proxy_env_var.empty?
1201
+ if %r{^.*://}.match?(proxy_env_var)
1202
+ URI.parse(proxy_env_var)
1203
+ else
1204
+ URI.parse("#{scheme}://#{proxy_env_var}")
1205
+ end
1206
+ end
1207
+
1208
+ return proxy unless fuzzy_hostname_match_any?(host, ENV["no_proxy"])
1209
+ end
1210
+
1211
+ # Chef requires an English-language UTF-8 locale to function properly. We attempt
1212
+ # to use the 'locale -a' command and search through a list of preferences until we
1213
+ # find one that we can use. On Ubuntu systems we should find 'C.UTF-8' and be
1214
+ # able to use that even if there is no English locale on the server, but Mac, Solaris,
1215
+ # AIX, etc do not have that locale. We then try to find an English locale and fall
1216
+ # back to 'C' if we do not. The choice of fallback is pick-your-poison. If we try
1217
+ # to do the work to return a non-US UTF-8 locale then we fail inside of providers when
1218
+ # things like 'svn info' return Japanese and we can't parse them. OTOH, if we pick 'C' then
1219
+ # we will blow up on UTF-8 characters. Between the warn we throw and the Encoding
1220
+ # exception that ruby will throw it is more obvious what is broken if we drop UTF-8 by
1221
+ # default rather than drop English.
1222
+ #
1223
+ # If there is no 'locale -a' then we return 'en_US.UTF-8' since that is the most commonly
1224
+ # available English UTF-8 locale. However, all modern POSIXen should support 'locale -a'.
1225
+ def self.guess_internal_locale
1226
+ # https://github.com/chef/chef/issues/2181
1227
+ # Some systems have the `locale -a` command, but the result has
1228
+ # invalid characters for the default encoding.
1229
+ #
1230
+ # For example, on CentOS 6 with ENV['LANG'] = "en_US.UTF-8",
1231
+ # `locale -a`.split fails with ArgumentError invalid UTF-8 encoding.
1232
+ cmd = Mixlib::ShellOut.new("locale -a").run_command
1233
+ cmd.error!
1234
+ locales = cmd.stdout.split
1235
+ case
1236
+ when locales.include?("C.UTF-8")
1237
+ "C.UTF-8"
1238
+ when locales.include?("en_US.UTF-8"), locales.include?("en_US.utf8")
1239
+ "en_US.UTF-8"
1240
+ when locales.include?("en.UTF-8")
1241
+ "en.UTF-8"
1242
+ else
1243
+ # Will match en_ZZ.UTF-8, en_ZZ.utf-8, en_ZZ.UTF8, en_ZZ.utf8
1244
+ guesses = locales.grep(/^en_.*UTF-?8$/i)
1245
+ unless guesses.empty?
1246
+ guessed_locale = guesses.first
1247
+ # Transform into the form en_ZZ.UTF-8
1248
+ guessed_locale.gsub(/UTF-?8$/i, "UTF-8")
1249
+ else
1250
+ 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."
1251
+ "C"
1252
+ end
1253
+ end
1254
+ rescue
1255
+ if ChefUtils.windows?
1256
+ ChefConfig.logger.trace "Defaulting to locale en_US.UTF-8 on Windows, until it matters that we do something else."
1257
+ else
1258
+ ChefConfig.logger.trace "No usable locale -a command found, assuming you have en_US.UTF-8 installed."
1259
+ end
1260
+ "en_US.UTF-8"
1261
+ end
1262
+
1263
+ default :internal_locale, guess_internal_locale
1264
+
1265
+ # Force UTF-8 Encoding, for when we fire up in the 'C' locale or other strange locales (e.g.
1266
+ # japanese windows encodings). If we do not do this, then knife upload will fail when a cookbook's
1267
+ # README.md has UTF-8 characters that do not encode in whatever surrounding encoding we have been
1268
+ # passed. Effectively, the Chef Ecosystem is globally UTF-8 by default. Anyone who wants to be
1269
+ # able to upload Shift_JIS or ISO-8859-1 files needs to mark *those* files explicitly with
1270
+ # magic tags to make ruby correctly identify the encoding being used. Changing this default will
1271
+ # break Chef community cookbooks and is very highly discouraged.
1272
+ default :ruby_encoding, Encoding::UTF_8
1273
+
1274
+ # can be set to a string or array of strings for URIs to set as rubygems sources
1275
+ default :rubygems_url, nil
1276
+
1277
+ # globally sets the default of the clear_sources property on the gem_package and chef_gem resources
1278
+ default :clear_gem_sources, nil
1279
+
1280
+ # If installed via an omnibus installer, this gives the path to the
1281
+ # "embedded" directory which contains all of the software packaged with
1282
+ # omnibus. This is used to locate the cacert.pem file on windows.
1283
+ def self.embedded_dir
1284
+ Pathname.new(_this_file).ascend do |path|
1285
+ if path.basename.to_s == "embedded"
1286
+ return path.to_s
1287
+ end
1288
+ end
1289
+
1290
+ nil
1291
+ end
1292
+
1293
+ # Path to this file in the current install.
1294
+ def self._this_file
1295
+ File.expand_path(__FILE__)
1296
+ end
1297
+
1298
+ # Set fips mode in openssl. Do any patching necessary to make
1299
+ # sure Chef runs do not crash.
1300
+ # @api private
1301
+ def self.enable_fips_mode
1302
+ OpenSSL.fips_mode = true
1303
+ require "digest" unless defined?(Digest)
1304
+ require "digest/sha1" unless defined?(Digest::SHA1)
1305
+ require "digest/md5" unless defined?(Digest::MD5)
1306
+ # Remove pre-existing constants if they do exist to reduce the
1307
+ # amount of log spam and warnings.
1308
+ Digest.send(:remove_const, "SHA1") if Digest.const_defined?(:SHA1)
1309
+ Digest.const_set(:SHA1, OpenSSL::Digest::SHA1)
1310
+ OpenSSL::Digest.send(:remove_const, "MD5") if OpenSSL::Digest.const_defined?(:MD5)
1311
+ OpenSSL::Digest.const_set(:MD5, Digest::MD5)
1312
+ ChefConfig.logger.debug "FIPS mode is enabled."
1313
+ end
1314
+ end
1315
+ end