chef-config 17.10.0 → 17.10.19

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