chef-config 18.3.0 → 19.3.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4eb9cf6e54784c6960ec4f0ed42aca3c398067aef6d0cbaac6b15c5cba59c656
4
- data.tar.gz: cf37fd7bd622d9d01d05bfdc53d8773a9c7f4b4614e035a0ccf8af04c95b6e3d
3
+ metadata.gz: 2b694ef61ad31b8917bea150e4327931d313d2e930417744dbb6b6ff4150e571
4
+ data.tar.gz: b60d0ccd47adfa4e046ffe14d2bd21f5965ea991b0f5bdd426cff0f336cecba1
5
5
  SHA512:
6
- metadata.gz: f2a005c3e964ffdf3e7e66da38b376b23fe26a0e7d0b19ef231f8740d371d7db3528fe54ebfc7c958793388736d40ca94c08e57497e3b3e96223fd45f51e3458
7
- data.tar.gz: ba3a02ad1c923f7c3d5912de6f3b8f6d3bbb70df0ab94c7ff4a79015b0f2b858848689bef5b6948c71adc7f56f594cd3cb82f49fdab3c2997b2b545104265e36
6
+ metadata.gz: 21d1abd0ac079d9e9b78c1d967a18a95c73bb8f0c03bd161fdba41b655d590dbaec0194bd7d5bd641bcacfc34ca51497c08113e2296902bc9a97c0cd54a79892
7
+ data.tar.gz: 6e600ea85ccaa3140566b71b4068a81e50290e18140dce57e57a1af1c19fc64d3e68d20c573b04303a91a33388d029af7713d3ed7396918b3db46c13c3f87dbc
data/chef-config.gemspec CHANGED
@@ -29,7 +29,8 @@ Gem::Specification.new do |spec|
29
29
  spec.add_dependency "mixlib-config", ">= 2.2.12", "< 4.0"
30
30
  spec.add_dependency "fuzzyurl"
31
31
  spec.add_dependency "addressable"
32
- spec.add_dependency "tomlrb", "~> 1.2"
32
+ spec.add_dependency "tomlrb", ">= 1.2", "< 3.0"
33
+ spec.add_dependency "racc"
33
34
 
34
35
  spec.files = %w{Rakefile LICENSE} + Dir.glob("*.gemspec") +
35
36
  Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
@@ -4,7 +4,7 @@
4
4
  # Author:: AJ Christensen (<aj@chef.io>)
5
5
  # Author:: Mark Mzyk (<mmzyk@chef.io>)
6
6
  # Author:: Kyle Goodwin (<kgoodwin@primerevenue.com>)
7
- # Copyright:: Copyright (c) Chef Software Inc.
7
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
8
8
  # License:: Apache License, Version 2.0
9
9
  #
10
10
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -97,8 +97,11 @@ module ChefConfig
97
97
  # @return [String] the platform-specific path
98
98
  #
99
99
  def self.var_chef_dir(windows: ChefUtils.windows?)
100
- path = windows ? c_chef_dir : PathHelper.join("/var", ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
101
- PathHelper.cleanpath(path, windows: windows)
100
+ @var_chef_dir ||= {}
101
+ @var_chef_dir[windows] ||= begin
102
+ path = windows ? c_chef_dir : PathHelper.join("/var", ChefUtils::Dist::Infra::DIR_SUFFIX, windows: windows)
103
+ PathHelper.cleanpath(path, windows: windows)
104
+ end
102
105
  end
103
106
 
104
107
  # On *nix, /var, on Windows C:\
@@ -107,8 +110,11 @@ module ChefConfig
107
110
  # @return [String] the platform-specific path
108
111
  #
109
112
  def self.var_root_dir(windows: ChefUtils.windows?)
110
- path = windows ? "C:\\" : "/var"
111
- PathHelper.cleanpath(path, windows: windows)
113
+ @var_root_dir ||= {}
114
+ @var_root_dir[windows] ||= begin
115
+ path = windows ? "C:\\" : "/var"
116
+ PathHelper.cleanpath(path, windows: windows)
117
+ end
112
118
  end
113
119
 
114
120
  # On windows, C:/chef/
@@ -415,7 +421,14 @@ module ChefConfig
415
421
  # If your `file_cache_path` resides on a NFS (or non-flock()-supporting
416
422
  # fs), it's recommended to set this to something like
417
423
  # '/tmp/chef-client-running.pid'
418
- default(:lockfile) { PathHelper.join(file_cache_path, "#{ChefUtils::Dist::Infra::CLIENT}-running.pid") }
424
+ # In Target Mode, the node name will be used as a prefix to allow
425
+ # parallel execution of Chef against different targets
426
+ default(:lockfile) do
427
+ prefix = ""
428
+ prefix = "#{ChefConfig::Config.node_name}-" if ChefConfig::Config.target_mode?
429
+
430
+ PathHelper.join(file_cache_path, "#{prefix}#{ChefUtils::Dist::Infra::CLIENT}-running.pid")
431
+ end
419
432
 
420
433
  ## Daemonization Settings ##
421
434
  # What user should Chef run as?
@@ -471,6 +484,14 @@ module ChefConfig
471
484
  # toggle info level log items that can create a lot of output
472
485
  default :verbose_logging, true
473
486
  default :node_name, nil
487
+
488
+ # When target mode is active, these hold the operator's original Chef Server
489
+ # identity so that API auth uses the admin credentials rather than the
490
+ # target node name. Set in Chef::Application::Client#reconfigure before
491
+ # target_mode.enabled is flipped to true.
492
+ default :api_client_name, nil
493
+ default :api_client_key, nil
494
+
474
495
  default :diff_disabled, false
475
496
  default :diff_filesize_threshold, 10000000
476
497
  default :diff_output_threshold, 1000000
@@ -911,7 +932,11 @@ module ChefConfig
911
932
  default :profile, nil
912
933
 
913
934
  default :chef_guid_path do
914
- PathHelper.join(config_dir, "#{ChefUtils::Dist::Infra::SHORT}_guid")
935
+ if target_mode?
936
+ PathHelper.join(config_dir, target_mode.host, "#{ChefUtils::Dist::Infra::SHORT}_guid")
937
+ else
938
+ PathHelper.join(config_dir, "#{ChefUtils::Dist::Infra::SHORT}_guid")
939
+ end
915
940
  end
916
941
 
917
942
  default :chef_guid, nil
@@ -1047,16 +1072,6 @@ module ChefConfig
1047
1072
  default :blocked_normal_attributes, nil
1048
1073
  default :blocked_override_attributes, nil
1049
1074
 
1050
- # deprecated config options that will be removed in Chef Infra Client 18
1051
- default :automatic_attribute_blacklist, nil
1052
- default :default_attribute_blacklist, nil
1053
- default :normal_attribute_blacklist, nil
1054
- default :override_attribute_blacklist, nil
1055
- default :automatic_attribute_whitelist, nil
1056
- default :default_attribute_whitelist, nil
1057
- default :normal_attribute_whitelist, nil
1058
- default :override_attribute_whitelist, nil
1059
-
1060
1075
  # Pull down all the rubygems versions from rubygems and cache them the first time we do a gem_package or
1061
1076
  # chef_gem install. This is memory-expensive and will grow without bounds, but will reduce network
1062
1077
  # round trips.
@@ -1205,7 +1220,7 @@ module ChefConfig
1205
1220
  end
1206
1221
  end
1207
1222
 
1208
- return proxy unless fuzzy_hostname_match_any?(host, ENV["no_proxy"])
1223
+ proxy unless fuzzy_hostname_match_any?(host, ENV["no_proxy"])
1209
1224
  end
1210
1225
 
1211
1226
  # Chef requires an English-language UTF-8 locale to function properly. We attempt
@@ -1299,7 +1314,9 @@ module ChefConfig
1299
1314
  # sure Chef runs do not crash.
1300
1315
  # @api private
1301
1316
  def self.enable_fips_mode
1317
+ # Enable FIPS mode in OpenSSL.
1302
1318
  OpenSSL.fips_mode = true
1319
+
1303
1320
  require "digest" unless defined?(Digest)
1304
1321
  require "digest/sha1" unless defined?(Digest::SHA1)
1305
1322
  require "digest/md5" unless defined?(Digest::MD5)
@@ -1307,8 +1324,6 @@ module ChefConfig
1307
1324
  # amount of log spam and warnings.
1308
1325
  Digest.send(:remove_const, "SHA1") if Digest.const_defined?(:SHA1)
1309
1326
  Digest.const_set(:SHA1, OpenSSL::Digest::SHA1)
1310
- OpenSSL::Digest.send(:remove_const, "MD5") if OpenSSL::Digest.const_defined?(:MD5)
1311
- OpenSSL::Digest.const_set(:MD5, Digest::MD5)
1312
1327
  ChefConfig.logger.debug "FIPS mode is enabled."
1313
1328
  end
1314
1329
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: Copyright (c) Chef Software Inc.
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,5 +23,8 @@ module ChefConfig
23
23
  class ConfigurationError < ArgumentError; end
24
24
  class InvalidPath < StandardError; end
25
25
  class UnparsableConfigOption < StandardError; end
26
+ class NoCredentialsFound < StandardError; end
26
27
 
28
+ class UnsupportedSecretsProvider < ConfigurationError; end
29
+ class UnresolvedSecret < ConfigurationError; end
27
30
  end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Matt Wrock (<matt@mattwrock.com>)
3
- # Copyright:: Copyright (c) Chef Software Inc.
3
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: Copyright (c) Chef Software Inc.
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: Copyright (c) Chef Software Inc.
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,6 +26,8 @@ module ChefConfig
26
26
  # @since 13.7
27
27
  # @api internal
28
28
  module Credentials
29
+ attr_reader :credentials_config
30
+
29
31
  # Compute the active credentials profile name.
30
32
  #
31
33
  # The lookup order is argument (from --profile), environment variable
@@ -54,6 +56,11 @@ module ChefConfig
54
56
  # @since 14.4
55
57
  # @return [String]
56
58
  def credentials_file_path
59
+ return Chef::Config[:credentials] if defined?(Chef::Config) && Chef::Config.key?(:credentials)
60
+
61
+ env_file = ENV["CHEF_CREDENTIALS_FILE"]
62
+ return env_file if env_file && File.file?(env_file)
63
+
57
64
  PathHelper.home(ChefUtils::Dist::Infra::USER_CONF_DIR, "credentials").freeze
58
65
  end
59
66
 
@@ -68,7 +75,7 @@ module ChefConfig
68
75
  return nil unless File.file?(credentials_file)
69
76
 
70
77
  begin
71
- Tomlrb.load_file(credentials_file)
78
+ @credentials_config = Tomlrb.load_file(credentials_file)
72
79
  rescue => e
73
80
  # TOML's error messages are mostly rubbish, so we'll just give a generic one
74
81
  message = "Unable to parse Credentials file: #{credentials_file}\n"
@@ -85,17 +92,129 @@ module ChefConfig
85
92
  # @return [void]
86
93
  def load_credentials(profile = nil)
87
94
  profile = credentials_profile(profile)
88
- cred_config = parse_credentials_file
89
- return if cred_config.nil? # No credentials, nothing to do here.
90
95
 
91
- if cred_config[profile].nil?
96
+ parse_credentials_file
97
+ return if credentials_config.nil? # No credentials, nothing to do here.
98
+
99
+ if credentials_config[profile].nil?
92
100
  # Unknown profile name. For "default" just silently ignore, otherwise
93
101
  # raise an error.
94
102
  return if profile == "default"
95
103
 
96
104
  raise ChefConfig::ConfigurationError, "Profile #{profile} doesn't exist. Please add it to #{credentials_file_path}."
97
105
  end
98
- apply_credentials(cred_config[profile], profile)
106
+
107
+ resolve_secrets(profile)
108
+
109
+ apply_credentials(credentials_config[profile], profile)
110
+ end
111
+
112
+ GLOBAL_CONFIG_HASHES = %w{ default_secrets_provider }.freeze
113
+
114
+ # Extract global (non-profile) settings from credentials file.
115
+ #
116
+ # @since 19.1
117
+ # @return [Hash]
118
+ def global_options
119
+ globals = credentials_config.filter { |_, v| v.is_a? String }
120
+ globals.merge! credentials_config.filter { |k, _| GLOBAL_CONFIG_HASHES.include? k }
121
+ end
122
+
123
+ SUPPORTED_SECRETS_PROVIDERS = %w{ hashicorp-vault }.freeze
124
+
125
+ # Resolve all secrets in a credentials file
126
+ #
127
+ # @since 19.1
128
+ # @param profile [String] Profile to resolve secrets in.
129
+ # @return [Hash]
130
+ def resolve_secrets(profile)
131
+ return unless credentials_config
132
+ raise NoCredentialsFound.new("No credentials found for profile '#{profile}'") unless credentials_config[profile]
133
+
134
+ secrets = credentials_config[profile].filter { |k, v| v.is_a?(Hash) && v.keys.include?("secret") }
135
+ return if secrets.empty?
136
+
137
+ secrets.each do |option, secrets_config|
138
+ unless valid_secrets_provider?(secrets_config)
139
+ raise UnsupportedSecretsProvider.new("Unsupported credentials secrets provider on '#{option}' for profile '#{profile}'")
140
+ end
141
+
142
+ secrets_config.merge!(default_secrets_provider)
143
+
144
+ logger.debug("Resolving credentials secret '#{option}' for profile '#{profile}'")
145
+ begin
146
+ resolved_value = resolve_secret(secrets_config)
147
+ ensure
148
+ raise UnresolvedSecret.new("Could not resolve secret '#{option}' for profile '#{profile}'") if resolved_value.nil?
149
+ end
150
+
151
+ credentials_config[profile][option] = resolved_value
152
+ end
153
+ end
154
+
155
+ # Check, if referenced secrets provider is supported.
156
+ #
157
+ # @since 19.1
158
+ # @param secrets_config [Hash] Parsed contents of a secret in a profile.
159
+ # @return [true, false]
160
+ def valid_secrets_provider?(secrets_config)
161
+ provider_config = secrets_config["secrets_provider"] || default_secrets_provider
162
+ provider = provider_config["name"]
163
+
164
+ provider && SUPPORTED_SECRETS_PROVIDERS.include?(provider)
165
+ end
166
+
167
+ def default_secrets_provider
168
+ global_options["default_secrets_provider"]
169
+ end
170
+
171
+ # Resolve a specific secret.
172
+ #
173
+ # To be replaced later by a Train-like framework to support multiple backends.
174
+ #
175
+ # @since 19.1
176
+ # @param secrets_config [Hash] Parsed contents of a secret in a profile.
177
+ # @return [String]
178
+ def resolve_secret(secrets_config)
179
+ resolve_secret_hashicorp(secrets_config)
180
+ end
181
+
182
+ # Resolver logic for Hashicorp Vault.
183
+ #
184
+ # Local lazy loading of Gems which are not part of chef-config or chef-utils,
185
+ # but chef itself to be switched by a unified secrets mechanism for credentials
186
+ # and Chef DSL later. Showstopper mitigation for 19 GA.
187
+ #
188
+ # @since 19.1
189
+ # @param secrets_config [Hash] Parsed contents of a secret in a profile.
190
+ # @return [String]
191
+ def resolve_secret_hashicorp(secrets_config)
192
+ vault_config = secrets_config.transform_keys(&:to_sym)
193
+ vault_config[:address] = vault_config[:endpoint]
194
+
195
+ # Lazy require due to Gem being part of Chef and rarely used functionality
196
+ require "vault" unless defined? Vault
197
+ @vault ||= Vault::Client.new(vault_config)
198
+
199
+ secret = secrets_config["secret"]
200
+ engine = vault_config[:engine] || "secret"
201
+ engine_type = vault_config[:engine_type] || "kv2"
202
+ secret_value = case engine_type
203
+ when "kv", "kv1"
204
+ @vault.logical.read("#{engine_type}/#{secret}")
205
+ when "kv2"
206
+ @vault.kv(engine).read(secret)&.data
207
+ else
208
+ raise UnsupportedSecretsProvider.new("No support for secrets engine #{engine_type}")
209
+ end
210
+
211
+ # Always JSON for Hashicorp Vault, but this is future compatible to other providers
212
+ if secret_value.is_a?(Hash)
213
+ require "jmespath" unless defined? ::JMESPath
214
+ ::JMESPath.search(secrets_config["field"], secret_value)
215
+ else
216
+ secret_value
217
+ end
99
218
  end
100
219
  end
101
220
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: Copyright (c) Chef Software Inc.
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: Copyright (c) Chef Software Inc.
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -42,6 +42,11 @@ module ChefConfig
42
42
  # Do greedy matching by adding wildcard if it is not specified
43
43
  match = "*" + match unless match.start_with?("*")
44
44
  Fuzzyurl.matches?(Fuzzyurl.mask(hostname: match), hostname)
45
+ rescue ArgumentError
46
+ # Fuzzyurl cannot parse certain URL formats, notably IPv6 addresses
47
+ # (bare, bracketed, or embedded in URLs). When parsing fails, the URL
48
+ # cannot match a no_proxy pattern, so return false.
49
+ false
45
50
  end
46
51
 
47
52
  end
@@ -1,5 +1,5 @@
1
1
  # Author:: Bryan McLellan <btm@loftninjas.org>
2
- # Copyright:: Copyright (c) Chef Software Inc.
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,15 +36,17 @@ module ChefConfig
36
36
  #
37
37
  def load_credentials(profile)
38
38
  # Tomlrb.load_file returns a hash with keys as strings
39
- credentials = parse_credentials_file
40
- if contains_split_fqdn?(credentials, profile)
39
+ credentials_config = parse_credentials_file
40
+ if contains_split_fqdn?(credentials_config, profile)
41
41
  logger.warn("Credentials file #{credentials_file_path} contains target '#{profile}' as a Hash, expected a string.")
42
42
  logger.warn("Hostnames must be surrounded by single quotes, e.g. ['host.example.org']")
43
43
  end
44
44
 
45
+ resolve_secrets(profile)
46
+
45
47
  # host names must be specified in credentials file as ['foo.example.org'] with quotes
46
- if !credentials.nil? && !credentials[profile].nil?
47
- credentials[profile].transform_keys(&:to_sym) # return symbolized keys to match Train.options()
48
+ if !credentials_config.nil? && !credentials_config[profile].nil?
49
+ credentials_config[profile].transform_keys(&:to_sym) # return symbolized keys to match Train.options()
48
50
  else
49
51
  nil
50
52
  end
@@ -59,6 +61,8 @@ module ChefConfig
59
61
  # This will be a common mistake so we should catch it
60
62
  #
61
63
  def contains_split_fqdn?(hash, fqdn)
64
+ return unless fqdn.include?(".")
65
+
62
66
  fqdn.split(".").reduce(hash) do |h, k|
63
67
  v = h[k]
64
68
  if Hash === v
@@ -74,21 +78,25 @@ module ChefConfig
74
78
  #
75
79
  # Credentials file preference:
76
80
  #
77
- # 1) target_mode.credentials_file
78
- # 2) /etc/chef/TARGET_MODE_HOST/credentials
79
- # 3) #credentials_file_path from parent ($HOME/.chef/credentials)
81
+ # 1) environment variable CHEF_CREDENTIALS_FILE
82
+ # 2) target_mode.credentials_file
83
+ # 3) /etc/chef/TARGET_MODE_HOST/credentials
84
+ # 4) user configuration ($HOME/.chef/target_credentials)
80
85
  #
81
86
  def credentials_file_path
82
87
  tm_config = config.target_mode
83
88
  profile = tm_config.host
84
89
 
90
+ env_file = ENV["CHEF_CREDENTIALS_FILE"]
85
91
  credentials_file =
86
- if tm_config.credentials_file && File.exist?(tm_config.credentials_file)
92
+ if env_file && File.exist?(env_file)
93
+ env_file
94
+ elsif tm_config.credentials_file && File.exist?(tm_config.credentials_file)
87
95
  tm_config.credentials_file
88
96
  elsif File.exist?(config.platform_specific_path("#{ChefConfig::Config.etc_chef_dir}/#{profile}/credentials"))
89
97
  config.platform_specific_path("#{ChefConfig::Config.etc_chef_dir}/#{profile}/credentials")
90
98
  else
91
- super
99
+ PathHelper.home(ChefUtils::Dist::Infra::USER_CONF_DIR, "target_credentials").freeze
92
100
  end
93
101
 
94
102
  raise ArgumentError, "No credentials file found for target '#{profile}'" unless credentials_file
@@ -112,7 +120,7 @@ module ChefConfig
112
120
  # Load the credentials file, and place any valid settings into the train configuration
113
121
  credentials = load_credentials(tm_config.host)
114
122
 
115
- protocol = credentials[:transport_protocol] || tm_config.protocol
123
+ protocol = credentials&.dig(:transport_protocol) || tm_config.protocol
116
124
  train_config = tm_config.to_hash.select { |k| Train.options(protocol).key?(k) }
117
125
  logger.trace("Using target mode options from #{ChefUtils::Dist::Infra::PRODUCT} config file: #{train_config.keys.join(", ")}") if train_config
118
126
 
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Bryan McLellan <btm@loftninjas.org>
3
- # Copyright:: Copyright (c) Chef Software Inc.
3
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -57,13 +57,16 @@ module ChefConfig
57
57
 
58
58
  def self.join(*args, windows: ChefUtils.windows?)
59
59
  path_separator_regex = Regexp.escape(windows ? "#{File::SEPARATOR}#{BACKSLASH}" : File::SEPARATOR)
60
- trailing_slashes_regex = /[#{path_separator_regex}]+$/.freeze
61
- leading_slashes_regex = /^[#{path_separator_regex}]+/.freeze
60
+ trailing_slashes_regex = /[#{path_separator_regex}]+$/
61
+ leading_slashes_regex = /^[#{path_separator_regex}]+/
62
+ separator = path_separator(windows: windows)
62
63
 
63
- args.flatten.inject do |joined_path, component|
64
+ args.flatten!
65
+ args.inject do |joined_path, component|
64
66
  joined_path = joined_path.sub(trailing_slashes_regex, "")
65
67
  component = component.sub(leading_slashes_regex, "")
66
- joined_path + "#{path_separator(windows: windows)}#{component}"
68
+ joined_path << "#{separator}#{component}"
69
+ joined_path
67
70
  end
68
71
  end
69
72
 
@@ -149,11 +152,12 @@ module ChefConfig
149
152
  path = Pathname.new(path).cleanpath.to_s
150
153
  if windows
151
154
  # ensure all forward slashes are backslashes
152
- path.gsub(File::SEPARATOR, path_separator(windows: windows))
155
+ path.gsub!(File::SEPARATOR, path_separator(windows: windows))
153
156
  else
154
157
  # ensure all backslashes are forward slashes
155
- path.gsub(BACKSLASH, File::SEPARATOR)
158
+ path.gsub!(BACKSLASH, File::SEPARATOR)
156
159
  end
160
+ path
157
161
  end
158
162
 
159
163
  # This is not just escaping for something like use in Regexps, or in globs. For the former
@@ -248,7 +252,7 @@ module ChefConfig
248
252
  paths << ENV[@@per_tool_home_environment] if defined?(@@per_tool_home_environment) && @@per_tool_home_environment && ENV[@@per_tool_home_environment]
249
253
  paths << ENV["CHEF_HOME"] if ENV["CHEF_HOME"]
250
254
  if windows
251
- # By default, Ruby uses the the following environment variables to determine Dir.home:
255
+ # By default, Ruby uses the following environment variables to determine Dir.home:
252
256
  # HOME
253
257
  # HOMEDRIVE HOMEPATH
254
258
  # USERPROFILE
@@ -1,4 +1,4 @@
1
- # Copyright:: Copyright (c) Chef Software Inc.
1
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
2
2
  # License:: Apache License, Version 2.0
3
3
  #
4
4
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,5 +15,5 @@
15
15
 
16
16
  module ChefConfig
17
17
  CHEFCONFIG_ROOT = File.expand_path("..", __dir__)
18
- VERSION = "18.3.0".freeze
18
+ VERSION = "19.3.15".freeze
19
19
  end
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: Copyright (c) Chef Software Inc.
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Daniel DeLeo (<dan@chef.io>)
3
- # Copyright:: Copyright (c) Chef Software Inc.
3
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
data/lib/chef-config.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright:: Copyright (c) Chef Software Inc.
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
3
3
  # License:: Apache License, Version 2.0
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,7 +1,7 @@
1
1
  #
2
2
  # Author:: Adam Jacob (<adam@chef.io>)
3
3
  # Author:: Kyle Goodwin (<kgoodwin@primerevenue.com>)
4
- # Copyright:: Copyright (c) Chef Software Inc.
4
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -22,8 +22,13 @@ require "chef-config/config"
22
22
  require "date" unless defined?(Date)
23
23
 
24
24
  RSpec.describe ChefConfig::Config do
25
+ let(:target_mode_host) { "fluffy.kittens.org".freeze }
26
+
25
27
  before(:each) do
26
28
  ChefConfig::Config.reset
29
+ ChefConfig::Config.instance_variable_set(:@var_chef_dir, nil)
30
+ ChefConfig::Config.instance_variable_set(:@etc_chef_dir, nil)
31
+ ChefConfig::Config.instance_variable_set(:@var_root_dir, nil)
27
32
 
28
33
  # By default, treat deprecation warnings as errors in tests.
29
34
  ChefConfig::Config.treat_deprecation_warnings_as_errors(true)
@@ -243,16 +248,18 @@ RSpec.describe ChefConfig::Config do
243
248
  end
244
249
 
245
250
  context "on windows", :windows_only do
246
- it "var_chef_dir is C:\\chef" do
247
- expect(ChefConfig::Config.var_chef_dir).to eql("C:\\#{dirname}")
251
+ let(:windows_drive) { ChefConfig::Config.windows_installation_drive || "C:" }
252
+
253
+ it "var_chef_dir is on the windows installation drive" do
254
+ expect(ChefConfig::Config.var_chef_dir).to eql("#{windows_drive}\\#{dirname}")
248
255
  end
249
256
 
250
257
  it "var_root_dir is C:\\" do
251
258
  expect(ChefConfig::Config.var_root_dir).to eql("C:\\")
252
259
  end
253
260
 
254
- it "etc_chef_dir is C:\\chef" do
255
- expect(ChefConfig::Config.etc_chef_dir).to eql("C:\\#{dirname}")
261
+ it "etc_chef_dir is on the windows installation drive" do
262
+ expect(ChefConfig::Config.etc_chef_dir).to eql("#{windows_drive}\\#{dirname}")
256
263
  end
257
264
  end
258
265
 
@@ -271,16 +278,18 @@ RSpec.describe ChefConfig::Config do
271
278
  end
272
279
 
273
280
  context "when forced to windows" do
274
- it "var_chef_dir is C:\\chef" do
275
- expect(ChefConfig::Config.var_chef_dir(windows: true)).to eql("C:\\#{dirname}")
281
+ let(:windows_drive) { ChefConfig::Config.windows_installation_drive || "C:" }
282
+
283
+ it "var_chef_dir is on the windows installation drive" do
284
+ expect(ChefConfig::Config.var_chef_dir(windows: true)).to eql("#{windows_drive}\\#{dirname}")
276
285
  end
277
286
 
278
287
  it "var_root_dir is C:\\" do
279
288
  expect(ChefConfig::Config.var_root_dir(windows: true)).to eql("C:\\")
280
289
  end
281
290
 
282
- it "etc_chef_dir is C:\\chef" do
283
- expect(ChefConfig::Config.etc_chef_dir(windows: true)).to eql("C:\\#{dirname}")
291
+ it "etc_chef_dir is on the windows installation drive" do
292
+ expect(ChefConfig::Config.etc_chef_dir(windows: true)).to eql("#{windows_drive}\\#{dirname}")
284
293
  end
285
294
  end
286
295
 
@@ -379,8 +388,6 @@ RSpec.describe ChefConfig::Config do
379
388
  end
380
389
 
381
390
  context "when target mode is enabled" do
382
- let(:target_mode_host) { "fluffy.kittens.org" }
383
-
384
391
  before do
385
392
  ChefConfig::Config.target_mode.enabled = true
386
393
  ChefConfig::Config.target_mode.host = target_mode_host
@@ -400,6 +407,25 @@ RSpec.describe ChefConfig::Config do
400
407
  end
401
408
  end
402
409
 
410
+ describe "ChefConfig::Config[:chef_guid_path]" do
411
+ it "sets the default path to the chef guid" do
412
+ expected_path = ChefConfig::PathHelper.join(ChefConfig::Config.config_dir, "chef_guid")
413
+ expect(ChefConfig::Config.chef_guid_path).to eq(expected_path)
414
+ end
415
+
416
+ context "when target mode is enabled" do
417
+ before do
418
+ ChefConfig::Config.target_mode.enabled = true
419
+ ChefConfig::Config.target_mode.host = target_mode_host
420
+ end
421
+
422
+ it "sets the default path to the chef guid with the target host name" do
423
+ expected_path = ChefConfig::PathHelper.join(ChefConfig::Config.config_dir, target_mode_host, "chef_guid")
424
+ expect(ChefConfig::Config.chef_guid_path).to eq(expected_path)
425
+ end
426
+ end
427
+ end
428
+
403
429
  describe "ChefConfig::Config[:fips]" do
404
430
  let(:fips_enabled) { false }
405
431
 
@@ -495,7 +521,6 @@ RSpec.describe ChefConfig::Config do
495
521
  end
496
522
 
497
523
  describe "ChefConfig::Config[:cache_path]" do
498
- let(:target_mode_host) { "fluffy.kittens.org" }
499
524
  let(:target_mode_primary_cache_path) { ChefUtils.windows? ? "#{primary_cache_path}\\#{target_mode_host}" : "#{primary_cache_path}/#{target_mode_host}" }
500
525
  let(:target_mode_secondary_cache_path) { ChefUtils.windows? ? "#{secondary_cache_path}\\#{target_mode_host}" : "#{secondary_cache_path}/#{target_mode_host}" }
501
526
 
@@ -710,9 +735,9 @@ RSpec.describe ChefConfig::Config do
710
735
 
711
736
  end
712
737
 
713
- # On Windows, we'll detect an omnibus build and set this to the
738
+ # On Windows, we'll detect embedded install and set this to the
714
739
  # cacert.pem included in the package, but it's nil if you're on Windows
715
- # w/o omnibus (e.g., doing development on Windows, custom build, etc.)
740
+ # w/o embedded install (e.g., doing development on Windows, custom build, etc.)
716
741
  unless is_windows
717
742
  it "ChefConfig::Config[:ssl_ca_file] defaults to nil" do
718
743
  expect(ChefConfig::Config[:ssl_ca_file]).to be_nil
@@ -842,7 +867,7 @@ RSpec.describe ChefConfig::Config do
842
867
  describe "finding the windows embedded dir" do
843
868
  let(:default_config_location) { "c:/opscode/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
844
869
  let(:alternate_install_location) { "c:/my/alternate/install/place/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
845
- let(:non_omnibus_location) { "c:/my/dev/stuff/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
870
+ let(:non_package_location) { "c:/my/dev/stuff/lib/ruby/gems/1.9.1/gems/chef-11.6.0/lib/chef/config.rb" }
846
871
 
847
872
  let(:default_ca_file) { "c:/opscode/chef/embedded/ssl/certs/cacert.pem" }
848
873
 
@@ -856,8 +881,8 @@ RSpec.describe ChefConfig::Config do
856
881
  expect(ChefConfig::Config.embedded_dir).to eq("c:/my/alternate/install/place/chef/embedded")
857
882
  end
858
883
 
859
- it "doesn't error when not in an omnibus install" do
860
- allow(ChefConfig::Config).to receive(:_this_file).and_return(non_omnibus_location)
884
+ it "doesn't error when not in an package install" do
885
+ allow(ChefConfig::Config).to receive(:_this_file).and_return(non_package_location)
861
886
  expect(ChefConfig::Config.embedded_dir).to be_nil
862
887
  end
863
888
 
@@ -0,0 +1,181 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
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
+ require "spec_helper"
19
+ require "chef-config/config"
20
+ require "chef-config/mixin/credentials"
21
+
22
+ module Vault
23
+ class Client; end
24
+ end
25
+
26
+ RSpec.describe ChefConfig::Mixin::Credentials do
27
+
28
+ let(:test_class) { Class.new { include ChefConfig::Mixin::Credentials } }
29
+ subject(:test_obj) { test_class.new }
30
+
31
+ describe "#credentials_profile" do
32
+ context "when an explicit profile is given" do
33
+ it "passes it through" do
34
+ expect(test_obj.credentials_profile("webserver")).to eq("webserver")
35
+ end
36
+ end
37
+
38
+ context "when an environment variable is set" do
39
+ before(:all) do
40
+ @original_env = ENV.to_hash
41
+ end
42
+
43
+ after(:all) do
44
+ ENV.clear
45
+ ENV.update(@original_env)
46
+ end
47
+
48
+ before(:each) do
49
+ ENV["CHEF_PROFILE"] = "acme-server"
50
+ end
51
+
52
+ it "picks the profile correctly" do
53
+ expect(test_obj.credentials_profile).to eq("acme-server")
54
+ end
55
+ end
56
+
57
+ context "when no profile is given" do
58
+ it "picks the default one" do
59
+ expect(test_obj.credentials_profile).to eq("default")
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "#resolve_secrets" do
65
+ context "when no credentials were loaded" do
66
+ it "returns" do
67
+ allow(test_obj).to receive(:credentials_config).and_return(nil)
68
+ expect(test_obj.resolve_secrets("dummy")).to eq(nil)
69
+ end
70
+ end
71
+
72
+ context "when credentials do not contain specified profile" do
73
+ it "raises an error" do
74
+ allow(test_obj).to receive(:credentials_config).and_return({ "webserver" => {} })
75
+ expect { test_obj.resolve_secrets("dummy") }.to raise_error(ChefConfig::NoCredentialsFound, /No credentials found for profile/)
76
+ end
77
+ end
78
+
79
+ context "when no secrets were referenced in profile" do
80
+ it "returns" do
81
+ allow(test_obj).to receive(:credentials_config).and_return({ "webserver2" => {} })
82
+ expect(test_obj.resolve_secrets("webserver2")).to eq(nil)
83
+ end
84
+ end
85
+ end
86
+
87
+ describe "#valid_secrets_provider?" do
88
+ context "when global, valid configuration was provided" do
89
+ let(:global_options) { { "default_secrets_provider" => { "name" => "hashicorp-vault", "endpoint" => "https://198.51.100.5:8200", "token" => "hvs.1234567890" } } }
90
+ let(:secrets_config) { { "secret" => "/chef/sudo_password", "field" => "password" } }
91
+
92
+ it "returns true" do
93
+ allow(test_obj).to receive(:global_options).and_return(global_options)
94
+ expect(test_obj.valid_secrets_provider?(secrets_config)).to be(true)
95
+ end
96
+ end
97
+
98
+ context "when global, invalid configuration was provided" do
99
+ let(:global_options) { { "default_secrets_provider" => { "name" => "hashicorp-consul" } } }
100
+ let(:secrets_config) { { "secret" => "/chef/sudo_password", "field" => "password" } }
101
+
102
+ it "returns false" do
103
+ allow(test_obj).to receive(:global_options).and_return(global_options)
104
+ expect(test_obj.valid_secrets_provider?(secrets_config)).to be(false)
105
+ end
106
+ end
107
+
108
+ context "when global, invalid configuration is overridden with a correct value" do
109
+ let(:global_options) { { "default_secrets_provider" => { "name" => "hashicorp-consul" } } }
110
+ let(:secrets_config) { { "secrets_provider" => { "name" => "hashicorp-vault" }, "secret" => "/chef/sudo_password", "field" => "password" } }
111
+
112
+ it "returns false" do
113
+ allow(test_obj).to receive(:global_options).and_return(global_options)
114
+ expect(test_obj.valid_secrets_provider?(secrets_config)).to be(true)
115
+ end
116
+ end
117
+ end
118
+
119
+ describe "#resolve_secret" do
120
+ before do
121
+ allow(test_obj).to receive(:global_options).and_return(global_options)
122
+
123
+ # Simulate "vault" gem
124
+ allow(test_obj).to receive(:require).with("vault")
125
+ vault_double = double("Vault::Client")
126
+ allow(vault_double).to receive_message_chain("logical.read") { secrets_result }
127
+ allow(vault_double).to receive_message_chain("kv.read.data") { secrets_result }
128
+ test_obj.instance_variable_set(:@vault, vault_double)
129
+
130
+ # Simulate "jmespath" gem
131
+ allow(test_obj).to receive(:require).with("jmespath")
132
+ jmespath_double = double("JMESPath")
133
+ allow(jmespath_double).to receive_message_chain("search") { search_for = secrets_config["field"]; secrets_result[search_for] }
134
+ stub_const("::JMESPath", jmespath_double)
135
+ end
136
+
137
+ context "without default secrets provider being set" do
138
+ let(:global_options) {}
139
+
140
+ context "for a secret of type string" do
141
+ let(:secrets_result) { "secret" }
142
+ let(:secrets_config) { { "secrets_provider" => { "name" => "hashicorp-vault" }, "secret" => "/chef/sudo_password" } }
143
+
144
+ it "returns the complete value" do
145
+ expect(test_obj.resolve_secret(secrets_config)).to eq("secret")
146
+ end
147
+ end
148
+
149
+ context "for a secret of type hash" do
150
+ let(:secrets_result) { { "password" => "secret" } }
151
+ let(:secrets_config) { { "secrets_provider" => { "name" => "hashicorp-vault", "endpoint" => "https://198.51.100.5:8200", "token" => "hvs.1234567890" }, "secret" => "/chef/sudo_password", "field" => "password" } }
152
+
153
+ it "returns the correct subkey" do
154
+ expect(test_obj.resolve_secret(secrets_config)).to eq("secret")
155
+ end
156
+ end
157
+ end
158
+
159
+ context "with default secrets provider being set" do
160
+ let(:global_options) { { "default_secrets_provider" => { "name" => "hashicorp-vault", "endpoint" => "https://198.51.100.5:8200", "token" => "hvs.1234567890" } } }
161
+
162
+ context "for a secret of type string" do
163
+ let(:secrets_result) { "secret" }
164
+ let(:secrets_config) { { "secret" => "/chef/sudo_password" } }
165
+
166
+ it "returns the complete value" do
167
+ expect(test_obj.resolve_secret(secrets_config)).to eq("secret")
168
+ end
169
+ end
170
+
171
+ context "for a secret of type hash" do
172
+ let(:secrets_result) { { "password" => "secret" } }
173
+ let(:secrets_config) { { "secret" => "/chef/sudo_password", "field" => "password" } }
174
+
175
+ it "returns the correct subkey" do
176
+ expect(test_obj.resolve_secret(secrets_config)).to eq("secret")
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Matt Wrock (<matt@mattwrock.com>)
3
- # Copyright:: Copyright (c) Chef Software Inc.
3
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -0,0 +1,70 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
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
+ require "spec_helper"
18
+ require "chef-config/mixin/fuzzy_hostname_matcher"
19
+
20
+ RSpec.describe ChefConfig::Mixin::FuzzyHostnameMatcher do
21
+ let(:matcher) do
22
+ Class.new { include ChefConfig::Mixin::FuzzyHostnameMatcher }.new
23
+ end
24
+
25
+ describe "#fuzzy_hostname_match?" do
26
+ it "matches a hostname with a wildcard pattern" do
27
+ expect(matcher.fuzzy_hostname_match?("foo.example.com", "example.com")).to be true
28
+ end
29
+
30
+ it "does not match unrelated hostnames" do
31
+ expect(matcher.fuzzy_hostname_match?("foo.example.com", "other.com")).to be false
32
+ end
33
+
34
+ it "returns false for bare IPv6 addresses instead of raising" do
35
+ expect(matcher.fuzzy_hostname_match?("2001:db8::1", "example.com")).to be false
36
+ end
37
+
38
+ it "returns false for bracketed IPv6 addresses instead of raising" do
39
+ expect(matcher.fuzzy_hostname_match?("[2001:db8::1]", "example.com")).to be false
40
+ end
41
+
42
+ it "returns false for IPv6 URLs instead of raising" do
43
+ expect(matcher.fuzzy_hostname_match?("https://[2001:db8::1]/path", "example.com")).to be false
44
+ end
45
+ end
46
+
47
+ describe "#fuzzy_hostname_match_any?" do
48
+ it "returns false when hostname is nil" do
49
+ expect(matcher.fuzzy_hostname_match_any?(nil, "example.com")).to be false
50
+ end
51
+
52
+ it "returns false when matches is nil" do
53
+ expect(matcher.fuzzy_hostname_match_any?("foo.example.com", nil)).to be false
54
+ end
55
+
56
+ it "matches against comma-separated patterns" do
57
+ expect(matcher.fuzzy_hostname_match_any?("foo.example.com", "other.com, example.com")).to be true
58
+ end
59
+
60
+ it "returns false for IPv6 URLs with hostname no_proxy patterns" do
61
+ ipv6_url = "https://[2001:db8:abcd:ef01::1]/organizations/o3"
62
+ no_proxy = "gateway.example.net,internal.example.com"
63
+ expect(matcher.fuzzy_hostname_match_any?(ipv6_url, no_proxy)).to be false
64
+ end
65
+
66
+ it "returns false for bare IPv6 with hostname no_proxy patterns" do
67
+ expect(matcher.fuzzy_hostname_match_any?("2001:db8::1", "example.com,other.net")).to be false
68
+ end
69
+ end
70
+ end
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Bryan McLellan <btm@loftninjas.org>
3
- # Copyright:: Copyright (c) Chef Software Inc.
3
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # Author:: Daniel DeLeo (<dan@chef.io>)
3
- # Copyright:: Copyright (c) Chef Software Inc.
3
+ # Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -480,11 +480,10 @@ RSpec.describe ChefConfig::WorkstationConfigLoader do
480
480
  node_name = 'barney'
481
481
  client_key = "barney_rubble.pem"
482
482
  chef_server_url = "https://api.chef.io/organizations/bedrock"
483
- knife = {
484
- secret_file = "/home/barney/.chef/encrypted_data_bag_secret.pem"
485
- }
483
+
486
484
  [default.knife]
487
485
  ssh_user = "knife_ssh_user"
486
+ secret_file = "/home/barney/.chef/encrypted_data_bag_secret.pem"
488
487
  EOH
489
488
  content
490
489
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 18.3.0
4
+ version: 19.3.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Jacob
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2023-08-29 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: chef-utils
@@ -16,14 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - '='
18
17
  - !ruby/object:Gem::Version
19
- version: 18.3.0
18
+ version: 19.3.15
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - '='
25
24
  - !ruby/object:Gem::Version
26
- version: 18.3.0
25
+ version: 19.3.15
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: mixlib-shellout
29
28
  requirement: !ruby/object:Gem::Requirement
@@ -96,17 +95,36 @@ dependencies:
96
95
  name: tomlrb
97
96
  requirement: !ruby/object:Gem::Requirement
98
97
  requirements:
99
- - - "~>"
98
+ - - ">="
100
99
  - !ruby/object:Gem::Version
101
100
  version: '1.2'
101
+ - - "<"
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
102
104
  type: :runtime
103
105
  prerelease: false
104
106
  version_requirements: !ruby/object:Gem::Requirement
105
107
  requirements:
106
- - - "~>"
108
+ - - ">="
107
109
  - !ruby/object:Gem::Version
108
110
  version: '1.2'
109
- description:
111
+ - - "<"
112
+ - !ruby/object:Gem::Version
113
+ version: '3.0'
114
+ - !ruby/object:Gem::Dependency
115
+ name: racc
116
+ requirement: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :runtime
122
+ prerelease: false
123
+ version_requirements: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
110
128
  email:
111
129
  - adam@chef.io
112
130
  executables: []
@@ -131,7 +149,9 @@ files:
131
149
  - lib/chef-config/workstation_config_loader.rb
132
150
  - spec/spec_helper.rb
133
151
  - spec/unit/config_spec.rb
152
+ - spec/unit/credentials_spec.rb
134
153
  - spec/unit/fips_spec.rb
154
+ - spec/unit/fuzzy_hostname_matcher_spec.rb
135
155
  - spec/unit/path_helper_spec.rb
136
156
  - spec/unit/workstation_config_loader_spec.rb
137
157
  homepage: https://github.com/chef/chef
@@ -143,7 +163,6 @@ metadata:
143
163
  documentation_uri: https://github.com/chef/chef/tree/main/chef-config/README.md
144
164
  homepage_uri: https://github.com/chef/chef/tree/main/chef-config
145
165
  source_code_uri: https://github.com/chef/chef/tree/main/chef-config
146
- post_install_message:
147
166
  rdoc_options: []
148
167
  require_paths:
149
168
  - lib
@@ -158,8 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
177
  - !ruby/object:Gem::Version
159
178
  version: '0'
160
179
  requirements: []
161
- rubygems_version: 3.3.7
162
- signing_key:
180
+ rubygems_version: 3.6.9
163
181
  specification_version: 4
164
182
  summary: Chef Infra's default configuration and config loading library
165
183
  test_files: []