chef 17.2.29 → 17.3.48

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +4 -3
  3. data/chef.gemspec +1 -0
  4. data/lib/chef/client.rb +1 -1
  5. data/lib/chef/data_bag.rb +1 -2
  6. data/lib/chef/data_bag_item.rb +1 -2
  7. data/lib/chef/deprecated.rb +10 -4
  8. data/lib/chef/dsl.rb +1 -0
  9. data/lib/chef/dsl/render_helpers.rb +44 -0
  10. data/lib/chef/dsl/secret.rb +64 -0
  11. data/lib/chef/dsl/toml.rb +116 -0
  12. data/lib/chef/dsl/universal.rb +5 -0
  13. data/lib/chef/exceptions.rb +22 -0
  14. data/lib/chef/handler/slow_report.rb +1 -1
  15. data/lib/chef/json_compat.rb +1 -1
  16. data/lib/chef/policy_builder/policyfile.rb +88 -45
  17. data/lib/chef/provider/file.rb +2 -2
  18. data/lib/chef/provider/lwrp_base.rb +1 -1
  19. data/lib/chef/provider/package/habitat.rb +168 -0
  20. data/lib/chef/provider/package/powershell.rb +5 -0
  21. data/lib/chef/providers.rb +1 -0
  22. data/lib/chef/resource/chef_client_config.rb +7 -2
  23. data/lib/chef/resource/chef_client_cron.rb +1 -1
  24. data/lib/chef/resource/chef_client_launchd.rb +1 -1
  25. data/lib/chef/resource/chef_client_scheduled_task.rb +1 -1
  26. data/lib/chef/resource/chef_client_systemd_timer.rb +1 -1
  27. data/lib/chef/resource/chef_client_trusted_certificate.rb +2 -2
  28. data/lib/chef/resource/chef_vault_secret.rb +2 -2
  29. data/lib/chef/resource/dsc_resource.rb +1 -1
  30. data/lib/chef/resource/execute.rb +3 -3
  31. data/lib/chef/resource/gem_package.rb +2 -1
  32. data/lib/chef/resource/habitat/_habitat_shared.rb +28 -0
  33. data/lib/chef/resource/habitat/habitat_package.rb +129 -0
  34. data/lib/chef/resource/habitat/habitat_sup.rb +329 -0
  35. data/lib/chef/resource/habitat/habitat_sup_systemd.rb +67 -0
  36. data/lib/chef/resource/habitat/habitat_sup_windows.rb +90 -0
  37. data/lib/chef/resource/habitat_config.rb +107 -0
  38. data/lib/chef/resource/habitat_install.rb +247 -0
  39. data/lib/chef/resource/habitat_service.rb +451 -0
  40. data/lib/chef/resource/habitat_user_toml.rb +92 -0
  41. data/lib/chef/resource/lwrp_base.rb +1 -1
  42. data/lib/chef/resource/support/HabService.dll.config.erb +19 -0
  43. data/lib/chef/resource/support/client.erb +8 -1
  44. data/lib/chef/resource/support/sup.toml.erb +179 -0
  45. data/lib/chef/resource/windows_defender.rb +163 -0
  46. data/lib/chef/resource/windows_defender_exclusion.rb +125 -0
  47. data/lib/chef/resource/windows_printer.rb +78 -44
  48. data/lib/chef/resource/windows_printer_port.rb +1 -1
  49. data/lib/chef/resource/windows_update_settings.rb +259 -0
  50. data/lib/chef/resources.rb +12 -1
  51. data/lib/chef/secret_fetcher.rb +54 -0
  52. data/lib/chef/secret_fetcher/aws_secrets_manager.rb +53 -0
  53. data/lib/chef/secret_fetcher/azure_key_vault.rb +56 -0
  54. data/lib/chef/secret_fetcher/base.rb +72 -0
  55. data/lib/chef/secret_fetcher/example.rb +46 -0
  56. data/lib/chef/version.rb +1 -1
  57. data/spec/functional/mixin/from_file_spec.rb +1 -1
  58. data/spec/integration/recipes/recipe_dsl_spec.rb +1 -1
  59. data/spec/integration/recipes/resource_action_spec.rb +4 -4
  60. data/spec/support/shared/unit/provider/file.rb +2 -8
  61. data/spec/unit/data_bag_item_spec.rb +2 -2
  62. data/spec/unit/data_bag_spec.rb +1 -1
  63. data/spec/unit/dsl/render_helpers_spec.rb +102 -0
  64. data/spec/unit/dsl/secret_spec.rb +65 -0
  65. data/spec/unit/policy_builder/dynamic_spec.rb +0 -5
  66. data/spec/unit/policy_builder/policyfile_spec.rb +144 -56
  67. data/spec/unit/provider/apt_update_spec.rb +3 -1
  68. data/spec/unit/provider/mount/aix_spec.rb +1 -1
  69. data/spec/unit/provider/package/powershell_spec.rb +74 -12
  70. data/spec/unit/resource/windows_defender_exclusion_spec.rb +62 -0
  71. data/spec/unit/resource/windows_defender_spec.rb +71 -0
  72. data/spec/unit/resource/windows_update_settings_spec.rb +64 -0
  73. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +63 -0
  74. data/spec/unit/secret_fetcher_spec.rb +82 -0
  75. metadata +51 -7
@@ -58,6 +58,14 @@ require_relative "resource/ips_package"
58
58
  require_relative "resource/gem_package"
59
59
  require_relative "resource/scm/git"
60
60
  require_relative "resource/group"
61
+ require_relative "resource/habitat/habitat_package"
62
+ require_relative "resource/habitat/habitat_sup"
63
+ require_relative "resource/habitat/habitat_sup_systemd"
64
+ require_relative "resource/habitat/habitat_sup_windows"
65
+ require_relative "resource/habitat_config"
66
+ require_relative "resource/habitat_install"
67
+ require_relative "resource/habitat_service"
68
+ require_relative "resource/habitat_user_toml"
61
69
  require_relative "resource/http_request"
62
70
  require_relative "resource/hostname"
63
71
  require_relative "resource/homebrew_cask"
@@ -148,6 +156,8 @@ require_relative "resource/windows_ad_join"
148
156
  require_relative "resource/windows_audit_policy"
149
157
  require_relative "resource/windows_auto_run"
150
158
  require_relative "resource/windows_certificate"
159
+ require_relative "resource/windows_defender"
160
+ require_relative "resource/windows_defender_exclusion"
151
161
  require_relative "resource/windows_dfs_folder"
152
162
  require_relative "resource/windows_dfs_namespace"
153
163
  require_relative "resource/windows_dfs_server"
@@ -167,7 +177,8 @@ require_relative "resource/windows_share"
167
177
  require_relative "resource/windows_shortcut"
168
178
  require_relative "resource/windows_task"
169
179
  require_relative "resource/windows_uac"
180
+ require_relative "resource/windows_update_settings"
170
181
  require_relative "resource/windows_workgroup"
171
182
  require_relative "resource/timezone"
172
183
  require_relative "resource/windows_user_privilege"
173
- require_relative "resource/windows_security_policy"
184
+ require_relative "resource/windows_security_policy"
@@ -0,0 +1,54 @@
1
+ #
2
+ # Author:: Marc Paradise (<marc@chef.io>)
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "exceptions"
20
+
21
+ class Chef
22
+ class SecretFetcher
23
+
24
+ SECRET_FETCHERS = %i{example aws_secrets_manager azure_key_vault}.freeze
25
+
26
+ # Returns a configured and validated instance
27
+ # of a [Chef::SecretFetcher::Base] for the given
28
+ # service and configuration.
29
+ #
30
+ # @param service [Symbol] the identifier for the service that will support this request. Must be in
31
+ # SECRET_FETCHERS
32
+ # @param config [Hash] configuration that the secrets service requires
33
+ def self.for_service(service, config)
34
+ fetcher = case service
35
+ when :example
36
+ require_relative "secret_fetcher/example"
37
+ Chef::SecretFetcher::Example.new(config)
38
+ when :aws_secrets_manager
39
+ require_relative "secret_fetcher/aws_secrets_manager"
40
+ Chef::SecretFetcher::AWSSecretsManager.new(config)
41
+ when :azure_key_vault
42
+ require_relative "secret_fetcher/azure_key_vault"
43
+ Chef::SecretFetcher::AzureKeyVault.new(config)
44
+ when nil, ""
45
+ raise Chef::Exceptions::Secret::MissingFetcher.new(SECRET_FETCHERS)
46
+ else
47
+ raise Chef::Exceptions::Secret::InvalidFetcherService.new("Unsupported secret service: #{service}", SECRET_FETCHERS)
48
+ end
49
+ fetcher.validate!
50
+ fetcher
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,53 @@
1
+ #
2
+ # Author:: Marc Paradise (<marc@chef.io>)
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "base"
20
+ require "aws-sdk-secretsmanager"
21
+
22
+ class Chef
23
+ # == Chef::SecretFetcher::AWSSecretsManager
24
+ # A fetcher that fetches a secret from AWS Secrets Manager
25
+ # In this initial iteration it defaults to authentication via instance profile.
26
+ # It is possible to pass options that configure it to use alternative credentials.
27
+ # This implementation supports fetching with version.
28
+ #
29
+ # NOTE: This does not yet support automatic retries, which the AWS client does by default.
30
+ #
31
+ # For configuration options see https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SecretsManager/Client.html#initialize-instance_method
32
+ #
33
+ # Note that ~/.aws default and environment-based configurations are supported by default in the
34
+ # ruby SDK.
35
+ #
36
+ # Usage Example:
37
+ #
38
+ # fetcher = SecretFetcher.for_service(:aws_secrets_manager, { region: "us-east-1" })
39
+ # fetcher.fetch("secretkey1", "v1")
40
+ class SecretFetcher
41
+ class AWSSecretsManager < Base
42
+ # @param identifier [String] the secret_id
43
+ # @param version [String] the secret version. Not usd at this time
44
+ # @return Aws::SecretsManager::Types::GetSecretValueResponse
45
+ def do_fetch(identifier, version)
46
+ client = Aws::SecretsManager::Client.new(config)
47
+ result = client.get_secret_value(secret_id: identifier, version_stage: version)
48
+ # These fields are mutually exclusive
49
+ result.secret_string || result.secret_binary
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,56 @@
1
+ require_relative "base"
2
+
3
+ class Chef
4
+ class SecretFetcher
5
+ # == Chef::SecretFetcher::AWSSecretsManager
6
+ # A fetcher that fetches a secret from Azure Key Vault. Supports fetching with version.
7
+ #
8
+ # In this initial iteration this authenticates via token obtained from the OAuth2 /token
9
+ # endpoint.
10
+ #
11
+ # Usage Example:
12
+ #
13
+ # fetcher = SecretFetcher.for_service(:azure_key_vault)
14
+ # fetcher.fetch("secretkey1", "v1")
15
+ class AzureKeyVault < Base
16
+ def validate!
17
+ @vault = config[:vault]
18
+ if @vault.nil?
19
+ raise Chef::Exceptions::Secret::MissingVaultName.new("You must provide a vault name to service options as vault: 'vault_name'")
20
+ end
21
+ end
22
+
23
+ def do_fetch(name, version)
24
+ token = fetch_token
25
+
26
+ # Note that `version` is optional after the final `/`. If nil/"", the latest secret version will be fetched.
27
+ secret_uri = URI.parse("https://#{@vault}.vault.azure.net/secrets/#{name}/#{version}?api-version=7.2")
28
+ http = Net::HTTP.new(secret_uri.host, secret_uri.port)
29
+ http.use_ssl = true
30
+
31
+ response = http.get(secret_uri, { "Authorization" => "Bearer #{token}",
32
+ "Content-Type" => "application/json" })
33
+
34
+ # If an exception is not raised, we can be reasonably confident of the
35
+ # shape of the result.
36
+ result = JSON.parse(response.body)
37
+ if result.key? "value"
38
+ result["value"]
39
+ else
40
+ raise Chef::Exceptions::Secret::FetchFailed.new("#{result["error"]["code"]}: #{result["error"]["message"]}")
41
+ end
42
+ end
43
+
44
+ def fetch_token
45
+ token_uri = URI.parse("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net")
46
+ http = Net::HTTP.new(token_uri.host, token_uri.port)
47
+ response = http.get(token_uri, { "Metadata" => "true" })
48
+ body = JSON.parse(response.body)
49
+ body["access_token"]
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+
56
+
@@ -0,0 +1,72 @@
1
+ #
2
+ # Author:: Marc Paradise (<marc@chef.io>)
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "../exceptions"
20
+
21
+ class Chef
22
+ # == Chef::SecretFetcher
23
+ # An abstract base class that defines the methods required to implement
24
+ # a Secret Fetcher.
25
+ class SecretFetcher
26
+ class Base
27
+ attr_reader :config
28
+
29
+ # Initialize a new SecretFetcher::Base
30
+ #
31
+ # @param config [Hash] Configuration hash. Expected configuration keys and values
32
+ # will vary based on implementation, and are validated in `validate!`.
33
+ def initialize(config)
34
+ @config = config
35
+ end
36
+
37
+ # Fetch the named secret by invoking implementation-specific [Chef::SecretFetcher::Base#do_fetch]
38
+ #
39
+ # @param name [Object] the name or identifier of the secret.
40
+ # @param version [Object] Optional version of the secret to fetch.
41
+ # @note - the name parameter will probably see a narrowing of type as we learn more about different integrations.
42
+ # @return [Object] the fetched secret
43
+ # @raise [Chef::Exceptions::Secret::MissingSecretName] when secret name is not provided
44
+ # @raise [Chef::Exceptions::Secret::FetchFailed] when the underlying attempt to fetch the secret fails.
45
+ def fetch(name, version = nil)
46
+ raise Chef::Exceptions::Secret::MissingSecretName.new if name.to_s == ""
47
+
48
+ do_fetch(name, version)
49
+ end
50
+
51
+ # Validate that the instance is correctly configured.
52
+ # @raise [Chef::Exceptions::Secret::ConfigurationInvalid] if it is not.
53
+ def validate!; end
54
+
55
+ # Called to fetch the secret identified by 'identifer'. Implementations
56
+ # should expect that `validate!` has been invoked before `do_fetch`.
57
+ #
58
+ # @param identifier [Object] Unique identifier of the secret to be retrieved.
59
+ # When invoked via DSL, this is pre-verified to be not nil/not empty string.
60
+ # The expected data type and form can vary by implementation.
61
+ # @param version [Object] Optional version of the secret to be retrieved. If not
62
+ # provided, implementations are expected to fetch the most recent version of the
63
+ # secret by default.
64
+ #
65
+ # @return [Object] The secret as returned from the implementation. The data type
66
+ # will vary implementation.
67
+ #
68
+ # @raise [Chef::Exceptions::Secret::FetchFailed] if the secret could not be fetched
69
+ def do_fetch(identifier, version); raise NotImplementedError.new; end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,46 @@
1
+ #
2
+ # Author:: Marc Paradise (<marc@chef.io>)
3
+ # Copyright:: Copyright (c) Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require_relative "base"
20
+
21
+ class Chef
22
+ # == Chef::SecretFetcher::Example
23
+ # A simple implementation of a secrets fetcher.
24
+ # It expects to be initialized with a hash of
25
+ # keys and secret values.
26
+ #
27
+ # Usage Example:
28
+ #
29
+ # fetcher = SecretFetcher.for_service(:example, "secretkey1" => { "secret" => "lives here" })
30
+ # fetcher.fetch("secretkey1")
31
+ class SecretFetcher
32
+ class Example < Base
33
+ def validate!
34
+ if config.class != Hash
35
+ raise Chef::Exceptions::Secret::ConfigurationInvalid.new("The Example fetcher requires a hash of secrets")
36
+ end
37
+ end
38
+
39
+ def do_fetch(identifier, version)
40
+ raise Chef::Exceptions::Secret::FetchFailed.new("Secret #{identifier}) not found.") unless config.key?(identifier)
41
+
42
+ config[identifier]
43
+ end
44
+ end
45
+ end
46
+ end
data/lib/chef/version.rb CHANGED
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("..", __dir__)
26
- VERSION = Chef::VersionString.new("17.2.29")
26
+ VERSION = Chef::VersionString.new("17.3.48")
27
27
  end
28
28
 
29
29
  #
@@ -33,7 +33,7 @@ describe Chef::Mixin::FromFile do
33
33
  end
34
34
 
35
35
  class ClassTestData
36
- class <<self
36
+ class << self
37
37
  include Chef::Mixin::FromFile
38
38
 
39
39
  def a(a = nil)
@@ -19,7 +19,7 @@ describe "Recipe DSL methods" do
19
19
  provides :base_thingy
20
20
  default_action :create
21
21
 
22
- class<<self
22
+ class << self
23
23
  attr_accessor :created_name
24
24
  attr_accessor :created_resource
25
25
  attr_accessor :created_provider
@@ -9,7 +9,7 @@ class NoActionJackson < Chef::Resource
9
9
  @foo
10
10
  end
11
11
 
12
- class <<self
12
+ class << self
13
13
  attr_accessor :action_was
14
14
  end
15
15
  end
@@ -17,7 +17,7 @@ end
17
17
  class WeirdActionJackson < Chef::Resource
18
18
  provides :weird_action_jackson
19
19
 
20
- class <<self
20
+ class << self
21
21
  attr_accessor :action_was
22
22
  end
23
23
 
@@ -176,7 +176,7 @@ module ResourceActionSpec
176
176
  @blarghle
177
177
  end
178
178
 
179
- class <<self
179
+ class << self
180
180
  attr_accessor :ran_action
181
181
  attr_accessor :succeeded
182
182
  attr_accessor :ruby_block_converged
@@ -284,7 +284,7 @@ module ResourceActionSpec
284
284
  @bar = "#{value}alope" if value
285
285
  @bar
286
286
  end
287
- class <<self
287
+ class << self
288
288
  attr_accessor :load_current_resource_ran
289
289
  attr_accessor :jackalope_ran
290
290
  end
@@ -43,7 +43,6 @@ end
43
43
  def setup_normal_file
44
44
  [ resource_path, normalized_path, windows_path].each do |path|
45
45
  allow(File).to receive(:file?).with(path).and_return(true)
46
- allow(File).to receive(:exists?).with(path).and_return(true)
47
46
  allow(File).to receive(:exist?).with(path).and_return(true)
48
47
  allow(File).to receive(:directory?).with(path).and_return(false)
49
48
  allow(File).to receive(:writable?).with(path).and_return(true)
@@ -57,7 +56,6 @@ def setup_missing_file
57
56
  [ resource_path, normalized_path, windows_path].each do |path|
58
57
  allow(File).to receive(:file?).with(path).and_return(false)
59
58
  allow(File).to receive(:realpath?).with(path).and_return(resource_path)
60
- allow(File).to receive(:exists?).with(path).and_return(false)
61
59
  allow(File).to receive(:exist?).with(path).and_return(false)
62
60
  allow(File).to receive(:directory?).with(path).and_return(false)
63
61
  allow(File).to receive(:writable?).with(path).and_return(false)
@@ -70,7 +68,6 @@ def setup_symlink
70
68
  [ resource_path, normalized_path, windows_path].each do |path|
71
69
  allow(File).to receive(:file?).with(path).and_return(true)
72
70
  allow(File).to receive(:realpath?).with(path).and_return(normalized_path)
73
- allow(File).to receive(:exists?).with(path).and_return(true)
74
71
  allow(File).to receive(:exist?).with(path).and_return(true)
75
72
  allow(File).to receive(:directory?).with(path).and_return(false)
76
73
  allow(File).to receive(:writable?).with(path).and_return(true)
@@ -84,7 +81,6 @@ def setup_unwritable_file
84
81
  [ resource_path, normalized_path, windows_path].each do |path|
85
82
  allow(File).to receive(:file?).with(path).and_return(false)
86
83
  allow(File).to receive(:realpath?).with(path).and_raise(Errno::ENOENT)
87
- allow(File).to receive(:exists?).with(path).and_return(true)
88
84
  allow(File).to receive(:exist?).with(path).and_return(true)
89
85
  allow(File).to receive(:directory?).with(path).and_return(false)
90
86
  allow(File).to receive(:writable?).with(path).and_return(false)
@@ -97,7 +93,6 @@ def setup_missing_enclosing_directory
97
93
  [ resource_path, normalized_path, windows_path].each do |path|
98
94
  allow(File).to receive(:file?).with(path).and_return(false)
99
95
  allow(File).to receive(:realpath?).with(path).and_raise(Errno::ENOENT)
100
- allow(File).to receive(:exists?).with(path).and_return(false)
101
96
  allow(File).to receive(:exist?).with(path).and_return(false)
102
97
  allow(File).to receive(:directory?).with(path).and_return(false)
103
98
  allow(File).to receive(:writable?).with(path).and_return(false)
@@ -138,7 +133,6 @@ shared_examples_for Chef::Provider::File do
138
133
  before(:each) do
139
134
  allow(content).to receive(:tempfile).and_return(tempfile)
140
135
  allow(File).to receive(:exist?).with(tempfile.path).and_call_original
141
- allow(File).to receive(:exists?).with(tempfile.path).and_call_original
142
136
  end
143
137
 
144
138
  after do
@@ -547,7 +541,7 @@ shared_examples_for Chef::Provider::File do
547
541
  provider.load_current_resource
548
542
  tempfile = double("Tempfile", path: "/tmp/foo-bar-baz")
549
543
  allow(content).to receive(:tempfile).and_return(tempfile)
550
- expect(File).to receive(:exists?).with("/tmp/foo-bar-baz").and_return(true)
544
+ expect(File).to receive(:exist?).with("/tmp/foo-bar-baz").and_return(true)
551
545
  expect(tempfile).to receive(:close).once
552
546
  expect(tempfile).to receive(:unlink).once
553
547
  end
@@ -630,7 +624,7 @@ shared_examples_for Chef::Provider::File do
630
624
  it "raises an exception when the content object returns a tempfile that does not exist" do
631
625
  tempfile = double("Tempfile", path: "/tmp/foo-bar-baz")
632
626
  expect(provider.send(:content)).to receive(:tempfile).at_least(:once).and_return(tempfile)
633
- expect(File).to receive(:exists?).with("/tmp/foo-bar-baz").and_return(false)
627
+ expect(File).to receive(:exist?).with("/tmp/foo-bar-baz").and_return(false)
634
628
  expect { provider.send(:do_contents_changes) }.to raise_error(RuntimeError)
635
629
  end
636
630
  end