chef 17.3.48-universal-mingw32 → 17.4.25-universal-mingw32
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 +4 -4
- data/lib/chef/application.rb +3 -1
- data/lib/chef/compliance/default_attributes.rb +5 -3
- data/lib/chef/compliance/runner.rb +15 -1
- data/lib/chef/dsl/secret.rb +3 -3
- data/lib/chef/exceptions.rb +0 -2
- data/lib/chef/formatters/error_mapper.rb +2 -2
- data/lib/chef/provider/execute.rb +1 -1
- data/lib/chef/provider/group/dscl.rb +1 -1
- data/lib/chef/provider/launchd.rb +6 -6
- data/lib/chef/provider/subversion.rb +4 -4
- data/lib/chef/provider/support/yum_repo.erb +1 -1
- data/lib/chef/provider/systemd_unit.rb +17 -16
- data/lib/chef/provider/user/mac.rb +3 -3
- data/lib/chef/provider/yum_repository.rb +27 -43
- data/lib/chef/provider/zypper_repository.rb +3 -3
- data/lib/chef/provider.rb +26 -1
- data/lib/chef/provider_resolver.rb +8 -2
- data/lib/chef/resource/homebrew_cask.rb +1 -1
- data/lib/chef/resource/inspec_waiver_file_entry.rb +2 -2
- data/lib/chef/resource/launchd.rb +3 -3
- data/lib/chef/resource/remote_file.rb +1 -1
- data/lib/chef/resource/rhsm_subscription.rb +5 -5
- data/lib/chef/resource/ruby_block.rb +100 -0
- data/lib/chef/resource/scm/subversion.rb +1 -1
- data/lib/chef/resource/sysctl.rb +2 -2
- data/lib/chef/resource/systemd_unit.rb +3 -3
- data/lib/chef/resource/yum_package.rb +1 -5
- data/lib/chef/resource.rb +14 -18
- data/lib/chef/resource_inspector.rb +6 -2
- data/lib/chef/secret_fetcher/aws_secrets_manager.rb +16 -4
- data/lib/chef/secret_fetcher/azure_key_vault.rb +31 -9
- data/lib/chef/secret_fetcher/base.rb +5 -1
- data/lib/chef/secret_fetcher.rb +5 -4
- data/lib/chef/version.rb +1 -1
- data/spec/integration/compliance/compliance_spec.rb +1 -0
- data/spec/integration/recipes/resource_action_spec.rb +2 -2
- data/spec/unit/compliance/runner_spec.rb +46 -2
- data/spec/unit/dsl/secret_spec.rb +8 -2
- data/spec/unit/provider_spec.rb +23 -0
- data/spec/unit/resource/homebrew_cask_spec.rb +29 -11
- data/spec/unit/resource/rhsm_subscription_spec.rb +50 -3
- data/spec/unit/resource/systemd_unit_spec.rb +1 -1
- data/spec/unit/resource_spec.rb +19 -8
- data/spec/unit/secret_fetcher/aws_secrets_manager_spec.rb +70 -0
- data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +23 -16
- data/spec/unit/secret_fetcher_spec.rb +9 -9
- metadata +7 -6
@@ -8,23 +8,30 @@ class Chef
|
|
8
8
|
# In this initial iteration this authenticates via token obtained from the OAuth2 /token
|
9
9
|
# endpoint.
|
10
10
|
#
|
11
|
-
#
|
11
|
+
# Validation of required configuration (vault name) is not performed until
|
12
|
+
# `fetch` time, to allow for embedding the vault name in with the secret
|
13
|
+
# name, such as "my_vault/secretkey1".
|
12
14
|
#
|
13
|
-
#
|
15
|
+
# @example
|
16
|
+
#
|
17
|
+
# fetcher = SecretFetcher.for_service(:azure_key_vault, { vault: "my_vault" }, run_context )
|
14
18
|
# fetcher.fetch("secretkey1", "v1")
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
#
|
22
|
+
# fetcher = SecretFetcher.for_service(:azure_key_vault, {}, run_context )
|
23
|
+
# fetcher.fetch("my_vault/secretkey1", "v1")
|
15
24
|
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
25
|
|
23
26
|
def do_fetch(name, version)
|
24
27
|
token = fetch_token
|
28
|
+
vault, name = resolve_vault_and_secret_name(name)
|
29
|
+
if vault.nil?
|
30
|
+
raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide a vault name to fetcher options as vault: 'vault_name' or in the secret name as 'vault_name/secret_name'")
|
31
|
+
end
|
25
32
|
|
26
33
|
# Note that `version` is optional after the final `/`. If nil/"", the latest secret version will be fetched.
|
27
|
-
secret_uri = URI.parse("https://#{
|
34
|
+
secret_uri = URI.parse("https://#{vault}.vault.azure.net/secrets/#{name}/#{version}?api-version=7.2")
|
28
35
|
http = Net::HTTP.new(secret_uri.host, secret_uri.port)
|
29
36
|
http.use_ssl = true
|
30
37
|
|
@@ -41,6 +48,21 @@ class Chef
|
|
41
48
|
end
|
42
49
|
end
|
43
50
|
|
51
|
+
# Determine the vault name and secret name from the provided name.
|
52
|
+
# If it is not in the provided name in the form "vault_name/secret_name"
|
53
|
+
# it will determine the vault name from `config[:vault]`.
|
54
|
+
# @param name [String] the secret name or vault and secret name in the form "vault_name/secret_name"
|
55
|
+
# @return Array[String, String] vault and secret name respectively
|
56
|
+
def resolve_vault_and_secret_name(name)
|
57
|
+
# We support a simplified approach where the vault name is not passed i
|
58
|
+
# into configuration, but
|
59
|
+
if name.include?("/")
|
60
|
+
name.split("/", 2)
|
61
|
+
else
|
62
|
+
[config[:vault], name]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
44
66
|
def fetch_token
|
45
67
|
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
68
|
http = Net::HTTP.new(token_uri.host, token_uri.port)
|
@@ -25,13 +25,17 @@ class Chef
|
|
25
25
|
class SecretFetcher
|
26
26
|
class Base
|
27
27
|
attr_reader :config
|
28
|
+
# Note that this is only available in the context of a recipe.
|
29
|
+
# Since that's the only place it's intended to be used, that's probably OK.
|
30
|
+
attr_reader :run_context
|
28
31
|
|
29
32
|
# Initialize a new SecretFetcher::Base
|
30
33
|
#
|
31
34
|
# @param config [Hash] Configuration hash. Expected configuration keys and values
|
32
35
|
# will vary based on implementation, and are validated in `validate!`.
|
33
|
-
def initialize(config)
|
36
|
+
def initialize(config, run_context)
|
34
37
|
@config = config
|
38
|
+
@run_context = run_context
|
35
39
|
end
|
36
40
|
|
37
41
|
# Fetch the named secret by invoking implementation-specific [Chef::SecretFetcher::Base#do_fetch]
|
data/lib/chef/secret_fetcher.rb
CHANGED
@@ -30,17 +30,18 @@ class Chef
|
|
30
30
|
# @param service [Symbol] the identifier for the service that will support this request. Must be in
|
31
31
|
# SECRET_FETCHERS
|
32
32
|
# @param config [Hash] configuration that the secrets service requires
|
33
|
-
|
33
|
+
# @param run_context [Chef::RunContext] the run context this is being invoked from
|
34
|
+
def self.for_service(service, config, run_context)
|
34
35
|
fetcher = case service
|
35
36
|
when :example
|
36
37
|
require_relative "secret_fetcher/example"
|
37
|
-
Chef::SecretFetcher::Example.new(config)
|
38
|
+
Chef::SecretFetcher::Example.new(config, run_context)
|
38
39
|
when :aws_secrets_manager
|
39
40
|
require_relative "secret_fetcher/aws_secrets_manager"
|
40
|
-
Chef::SecretFetcher::AWSSecretsManager.new(config)
|
41
|
+
Chef::SecretFetcher::AWSSecretsManager.new(config, run_context)
|
41
42
|
when :azure_key_vault
|
42
43
|
require_relative "secret_fetcher/azure_key_vault"
|
43
|
-
Chef::SecretFetcher::AzureKeyVault.new(config)
|
44
|
+
Chef::SecretFetcher::AzureKeyVault.new(config, run_context)
|
44
45
|
when nil, ""
|
45
46
|
raise Chef::Exceptions::Secret::MissingFetcher.new(SECRET_FETCHERS)
|
46
47
|
else
|
data/lib/chef/version.rb
CHANGED
@@ -354,8 +354,8 @@ module ResourceActionSpec
|
|
354
354
|
end
|
355
355
|
|
356
356
|
it "allows overridden action to have a description separate from the action defined in the base resource" do
|
357
|
-
expect(ActionJackson.action_description(:test1)).to eql "Original description"
|
358
|
-
expect(ActionJackalope.action_description(:test1)).to eql "An old action with a new description"
|
357
|
+
expect(ActionJackson.new("ActionJackson", nil).action_description(:test1)).to eql "Original description"
|
358
|
+
expect(ActionJackalope.new("ActionJackalope", nil).action_description(:test1)).to eql "An old action with a new description"
|
359
359
|
end
|
360
360
|
|
361
361
|
it "non-overridden actions run and can access overridden and non-overridden variables (but not necessarily new ones)" do
|
@@ -202,6 +202,16 @@ describe Chef::Compliance::Runner do
|
|
202
202
|
expect { runner.load_and_validate! }.to raise_error(/^CMPL002:/)
|
203
203
|
end
|
204
204
|
|
205
|
+
it "raises CMPL004 if both the inputs and attributes node attributes are set" do
|
206
|
+
node.normal["audit"]["attributes"] = {
|
207
|
+
"tacos" => "lunch",
|
208
|
+
}
|
209
|
+
node.normal["audit"]["inputs"] = {
|
210
|
+
"tacos" => "lunch",
|
211
|
+
}
|
212
|
+
expect { runner.load_and_validate! }.to raise_error(/^CMPL011:/)
|
213
|
+
end
|
214
|
+
|
205
215
|
it "validates configured reporters" do
|
206
216
|
node.normal["audit"]["reporter"] = [ "chef-automate" ]
|
207
217
|
reporter_double = double("reporter", validate_config!: nil)
|
@@ -212,6 +222,40 @@ describe Chef::Compliance::Runner do
|
|
212
222
|
end
|
213
223
|
|
214
224
|
describe "#inspec_opts" do
|
225
|
+
it "pulls inputs from the attributes setting" do
|
226
|
+
node.normal["audit"]["attributes"] = {
|
227
|
+
"tacos" => "lunch",
|
228
|
+
}
|
229
|
+
|
230
|
+
inputs = runner.inspec_opts[:inputs]
|
231
|
+
|
232
|
+
expect(inputs["tacos"]).to eq("lunch")
|
233
|
+
end
|
234
|
+
|
235
|
+
it "pulls inputs from the inputs setting" do
|
236
|
+
node.normal["audit"]["inputs"] = {
|
237
|
+
"tacos" => "lunch",
|
238
|
+
}
|
239
|
+
|
240
|
+
inputs = runner.inspec_opts[:inputs]
|
241
|
+
|
242
|
+
expect(inputs["tacos"]).to eq("lunch")
|
243
|
+
end
|
244
|
+
|
245
|
+
it "favors inputs over attributes" do
|
246
|
+
node.normal["audit"]["attributes"] = {
|
247
|
+
"tacos" => "dinner",
|
248
|
+
}
|
249
|
+
|
250
|
+
node.normal["audit"]["inputs"] = {
|
251
|
+
"tacos" => "lunch",
|
252
|
+
}
|
253
|
+
|
254
|
+
inputs = runner.inspec_opts[:inputs]
|
255
|
+
|
256
|
+
expect(inputs["tacos"]).to eq("lunch")
|
257
|
+
end
|
258
|
+
|
215
259
|
it "does not include chef_node in inputs by default" do
|
216
260
|
node.normal["audit"]["attributes"] = {
|
217
261
|
"tacos" => "lunch",
|
@@ -221,7 +265,7 @@ describe Chef::Compliance::Runner do
|
|
221
265
|
inputs = runner.inspec_opts[:inputs]
|
222
266
|
|
223
267
|
expect(inputs["tacos"]).to eq("lunch")
|
224
|
-
expect(inputs.key?("chef_node")).to eq(
|
268
|
+
expect(inputs.key?("chef_node")).to eq(true)
|
225
269
|
end
|
226
270
|
|
227
271
|
it "includes chef_node in inputs with chef_node_attribute_enabled set" do
|
@@ -234,7 +278,7 @@ describe Chef::Compliance::Runner do
|
|
234
278
|
inputs = runner.inspec_opts[:inputs]
|
235
279
|
|
236
280
|
expect(inputs["tacos"]).to eq("lunch")
|
237
|
-
expect(inputs["chef_node"]["audit"]["reporter"]).to eq(
|
281
|
+
expect(inputs["chef_node"]["audit"]["reporter"]).to eq("cli")
|
238
282
|
expect(inputs["chef_node"]["chef_environment"]).to eq("_default")
|
239
283
|
end
|
240
284
|
end
|
@@ -21,6 +21,12 @@ require "chef/dsl/secret"
|
|
21
21
|
require "chef/secret_fetcher/base"
|
22
22
|
class SecretDSLTester
|
23
23
|
include Chef::DSL::Secret
|
24
|
+
# Because DSL is invoked in the context of a recipe,
|
25
|
+
# we expect run_context to always be available when SecretFetcher::Base
|
26
|
+
# requests it - making it safe to mock here
|
27
|
+
def run_context
|
28
|
+
nil
|
29
|
+
end
|
24
30
|
end
|
25
31
|
|
26
32
|
class SecretFetcherImpl < Chef::SecretFetcher::Base
|
@@ -36,8 +42,8 @@ describe Chef::DSL::Secret do
|
|
36
42
|
end
|
37
43
|
|
38
44
|
it "uses SecretFetcher.for_service to find the fetcher" do
|
39
|
-
substitute_fetcher = SecretFetcherImpl.new({})
|
40
|
-
expect(Chef::SecretFetcher).to receive(:for_service).with(:example, {}).and_return(substitute_fetcher)
|
45
|
+
substitute_fetcher = SecretFetcherImpl.new({}, nil)
|
46
|
+
expect(Chef::SecretFetcher).to receive(:for_service).with(:example, {}, nil).and_return(substitute_fetcher)
|
41
47
|
expect(substitute_fetcher).to receive(:fetch).with("key1", nil)
|
42
48
|
dsl.secret(name: "key1", service: :example, config: {})
|
43
49
|
end
|
data/spec/unit/provider_spec.rb
CHANGED
@@ -32,6 +32,21 @@ class NoWhyrunDemonstrator < Chef::Provider
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
35
|
+
class ActionDescriptionDemonstrator < Chef::Provider
|
36
|
+
def load_current_resource; end
|
37
|
+
|
38
|
+
action :foo, description: "foo described" do
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
action :foo2 do
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
context "blah" do
|
49
|
+
end
|
35
50
|
class ConvergeActionDemonstrator < Chef::Provider
|
36
51
|
attr_reader :system_state_altered
|
37
52
|
|
@@ -98,6 +113,14 @@ describe Chef::Provider do
|
|
98
113
|
expect(@provider.action_nothing).to eql(true)
|
99
114
|
end
|
100
115
|
|
116
|
+
it "should return an action description for action_description when one is available" do
|
117
|
+
expect(ActionDescriptionDemonstrator.action_description(:foo)).to eq "foo described"
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should return nil for action_description when no description is available" do
|
121
|
+
expect(ActionDescriptionDemonstrator.action_description(:none)).to eq nil
|
122
|
+
end
|
123
|
+
|
101
124
|
it "evals embedded recipes with a pristine resource collection" do
|
102
125
|
@provider.run_context.instance_variable_set(:@resource_collection, "doesn't matter what this is")
|
103
126
|
temporary_collection = nil
|
@@ -19,22 +19,40 @@ require "spec_helper"
|
|
19
19
|
|
20
20
|
describe Chef::Resource::HomebrewCask do
|
21
21
|
|
22
|
-
|
22
|
+
context "name with under bar" do
|
23
|
+
let(:resource) { Chef::Resource::HomebrewCask.new("fakey_fakerton") }
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
it "has a resource name of :homebrew_cask" do
|
26
|
+
expect(resource.resource_name).to eql(:homebrew_cask)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "the cask_name property is the name_property" do
|
30
|
+
expect(resource.cask_name).to eql("fakey_fakerton")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sets the default action as :install" do
|
34
|
+
expect(resource.action).to eql([:install])
|
35
|
+
end
|
27
36
|
|
28
|
-
|
29
|
-
|
37
|
+
it "supports :install, :remove actions" do
|
38
|
+
expect { resource.action :install }.not_to raise_error
|
39
|
+
expect { resource.action :remove }.not_to raise_error
|
40
|
+
end
|
30
41
|
end
|
31
42
|
|
32
|
-
|
33
|
-
|
43
|
+
context "name with high fun" do
|
44
|
+
let(:resource) { Chef::Resource::HomebrewCask.new("fakey-fakerton") }
|
45
|
+
|
46
|
+
it "the cask_name property is the name_property" do
|
47
|
+
expect(resource.cask_name).to eql("fakey-fakerton")
|
48
|
+
end
|
34
49
|
end
|
35
50
|
|
36
|
-
|
37
|
-
|
38
|
-
|
51
|
+
context "name with at mark" do
|
52
|
+
let(:resource) { Chef::Resource::HomebrewCask.new("fakey-fakerton@10") }
|
53
|
+
|
54
|
+
it "the cask_name property is the name_property" do
|
55
|
+
expect(resource.cask_name).to eql("fakey-fakerton@10")
|
56
|
+
end
|
39
57
|
end
|
40
58
|
end
|
@@ -18,15 +18,24 @@
|
|
18
18
|
require "spec_helper"
|
19
19
|
|
20
20
|
describe Chef::Resource::RhsmSubscription do
|
21
|
-
let(:
|
22
|
-
let(:
|
21
|
+
let(:event_dispatch) { Chef::EventDispatch::Dispatcher.new }
|
22
|
+
let(:node) { Chef::Node.new }
|
23
|
+
let(:run_context) { Chef::RunContext.new(node, {}, event_dispatch) }
|
24
|
+
|
25
|
+
let(:pool_id) { "8a8dd78c766232550226b46e59404aba" }
|
26
|
+
let(:resource) { Chef::Resource::RhsmSubscription.new(pool_id, run_context) }
|
27
|
+
let(:provider) { resource.provider_for_action(Array(resource.action).first) }
|
28
|
+
|
29
|
+
before do
|
30
|
+
allow(resource).to receive(:provider_for_action).with(:attach).and_return(provider)
|
31
|
+
end
|
23
32
|
|
24
33
|
it "has a resource name of :rhsm_subscription" do
|
25
34
|
expect(resource.resource_name).to eql(:rhsm_subscription)
|
26
35
|
end
|
27
36
|
|
28
37
|
it "the pool_id property is the name_property" do
|
29
|
-
expect(resource.pool_id).to eql(
|
38
|
+
expect(resource.pool_id).to eql(pool_id)
|
30
39
|
end
|
31
40
|
|
32
41
|
it "sets the default action as :attach" do
|
@@ -38,6 +47,44 @@ describe Chef::Resource::RhsmSubscription do
|
|
38
47
|
expect { resource.action :remove }.not_to raise_error
|
39
48
|
end
|
40
49
|
|
50
|
+
describe "#action_attach" do
|
51
|
+
let(:yum_package_double) { instance_double("Chef::Resource::YumPackage") }
|
52
|
+
let(:so_double) { instance_double("Mixlib::ShellOut", stdout: "Successfully attached a subscription for: My Subscription", exitstatus: 0, error?: false) }
|
53
|
+
|
54
|
+
before do
|
55
|
+
allow(provider).to receive(:shell_out!).with("subscription-manager attach --pool=#{resource.pool_id}").and_return(so_double)
|
56
|
+
allow(provider).to receive(:build_resource).with(:package, "rhsm_subscription-#{pool_id}-flush_cache").and_return(yum_package_double)
|
57
|
+
allow(yum_package_double).to receive(:run_action).with(:flush_cache)
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when already attached to pool" do
|
61
|
+
before do
|
62
|
+
allow(provider).to receive(:subscription_attached?).with(resource.pool_id).and_return(true)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "does not attach to pool" do
|
66
|
+
expect(provider).not_to receive(:shell_out!)
|
67
|
+
resource.run_action(:attach)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when not attached to pool" do
|
72
|
+
before do
|
73
|
+
allow(provider).to receive(:subscription_attached?).with(resource.pool_id).and_return(false)
|
74
|
+
end
|
75
|
+
|
76
|
+
it "attaches to pool" do
|
77
|
+
expect(provider).to receive(:shell_out!).with("subscription-manager attach --pool=#{resource.pool_id}")
|
78
|
+
resource.run_action(:attach)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "flushes package provider cache" do
|
82
|
+
expect(yum_package_double).to receive(:run_action).with(:flush_cache)
|
83
|
+
resource.run_action(:attach)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
41
88
|
describe "#subscription_attached?" do
|
42
89
|
let(:cmd) { double("cmd") }
|
43
90
|
let(:output) { "Pool ID: pool123" }
|
@@ -20,7 +20,7 @@ require "spec_helper"
|
|
20
20
|
|
21
21
|
describe Chef::Resource::SystemdUnit do
|
22
22
|
let(:resource) { Chef::Resource::SystemdUnit.new("sysstat-collect.timer") }
|
23
|
-
let(:unit_content_string) { "[Unit]\nDescription
|
23
|
+
let(:unit_content_string) { "[Unit]\nDescription=Run system activity accounting tool every 10 minutes\nDocumentation=foo\nDocumentation=bar\n\n[Timer]\nOnCalendar=*:00/10\n\n[Install]\nWantedBy=sysstat.service\n" }
|
24
24
|
let(:unit_content_hash) do
|
25
25
|
{
|
26
26
|
"Unit" => {
|
data/spec/unit/resource_spec.rb
CHANGED
@@ -1172,21 +1172,23 @@ describe Chef::Resource do
|
|
1172
1172
|
action :base_action3, description: "unmodified base action 3 desc" do; end
|
1173
1173
|
end
|
1174
1174
|
|
1175
|
+
let(:resource_inst) { TestResource.new("TestResource", nil) }
|
1176
|
+
|
1175
1177
|
it "returns nil when no description was provided for the action" do
|
1176
|
-
expect(
|
1178
|
+
expect(resource_inst.action_description(:base_action0)).to eql(nil)
|
1177
1179
|
end
|
1178
1180
|
|
1179
1181
|
context "when action definition is a string" do
|
1180
1182
|
it "returns the description whether a symbol or string is used to look it up" do
|
1181
|
-
expect(
|
1182
|
-
expect(
|
1183
|
+
expect(resource_inst.action_description("string_action")).to eql("a string test")
|
1184
|
+
expect(resource_inst.action_description(:string_action)).to eql("a string test")
|
1183
1185
|
end
|
1184
1186
|
end
|
1185
1187
|
|
1186
1188
|
context "when action definition is a symbol" do
|
1187
1189
|
it "returns the description whether a symbol or string is used to look up" do
|
1188
|
-
expect(
|
1189
|
-
expect(
|
1190
|
+
expect(resource_inst.action_description("symbol_action")).to eql("a symbol test")
|
1191
|
+
expect(resource_inst.action_description(:symbol_action)).to eql("a symbol test")
|
1190
1192
|
end
|
1191
1193
|
end
|
1192
1194
|
|
@@ -1196,14 +1198,23 @@ describe Chef::Resource do
|
|
1196
1198
|
action :base_action3 do; end
|
1197
1199
|
end
|
1198
1200
|
|
1201
|
+
class TestResourceChild2 < TestResource
|
1202
|
+
# We should never see this description
|
1203
|
+
action :base_action2, description: "if you see this in an error, TestResourceChild was polluted with this description" do; end
|
1204
|
+
end
|
1205
|
+
let(:resource_inst) { TestResourceChild.new("TestResource", nil) }
|
1206
|
+
|
1199
1207
|
it "returns original description when a described action is not overridden in child resource" do
|
1200
|
-
expect(
|
1208
|
+
expect(resource_inst.action_description(:base_action1)).to eq "unmodified base action 1 desc"
|
1201
1209
|
end
|
1202
1210
|
it "returns original description when the child resource overrides an inherited action but NOT its description" do
|
1203
|
-
expect(
|
1211
|
+
expect(resource_inst.action_description(:base_action3)).to eq "unmodified base action 3 desc"
|
1212
|
+
end
|
1213
|
+
it "returns new description when the child resource overrides an inherited action and its description" do
|
1214
|
+
expect(resource_inst.action_description(:base_action2)).to eq "modified base action 2 desc"
|
1204
1215
|
end
|
1205
1216
|
it "returns new description when the child resource overrides an inherited action and its description" do
|
1206
|
-
expect(
|
1217
|
+
expect(resource_inst.action_description(:base_action2)).to eq "modified base action 2 desc"
|
1207
1218
|
end
|
1208
1219
|
end
|
1209
1220
|
end
|