chef-config 14.9.13 → 14.10.9

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