diff options
author | Lamont Granquist <454857+lamont-granquist@users.noreply.github.com> | 2022-03-29 13:04:03 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-29 13:04:03 -0700 |
commit | 2a33d348eedad45e8416a7487eb13fac337bdcfc (patch) | |
tree | e5ae17f909bf39872c161ac08f50ef34d3274490 /spec | |
parent | 20db13b428afd1975e4049ba7c8f5ee1645217bf (diff) | |
parent | ff68fd07a9fbcd5a7de89b30d3669819c4af8ed7 (diff) | |
download | chef-2a33d348eedad45e8416a7487eb13fac337bdcfc.tar.gz |
Merge pull request #12140 from jasonwbarnett/feature/allow-setting-default-secret-service
Diffstat (limited to 'spec')
-rw-r--r-- | spec/unit/dsl/secret_spec.rb | 150 | ||||
-rw-r--r-- | spec/unit/run_context_spec.rb | 16 |
2 files changed, 143 insertions, 23 deletions
diff --git a/spec/unit/dsl/secret_spec.rb b/spec/unit/dsl/secret_spec.rb index 96a915c43d..9952980697 100644 --- a/spec/unit/dsl/secret_spec.rb +++ b/spec/unit/dsl/secret_spec.rb @@ -17,11 +17,14 @@ # require "spec_helper" +require "chef/exceptions" require "chef/dsl/secret" require "chef/secret_fetcher/base" + class SecretDSLTester include Chef::DSL::Secret - # Because DSL is invoked in the context of a recipe, + + # Because DSL is invoked in the context of a recipe or attribute file # we expect run_context to always be available when SecretFetcher::Base # requests it - making it safe to mock here def run_context @@ -37,35 +40,136 @@ end describe Chef::DSL::Secret do let(:dsl) { SecretDSLTester.new } - it "responds to 'secret'" do - expect(dsl.respond_to?(:secret)).to eq true + let(:run_context) { Chef::RunContext.new(Chef::Node.new, {}, Chef::EventDispatch::Dispatcher.new) } + + before do + allow(dsl).to receive(:run_context).and_return(run_context) end - it "uses SecretFetcher.for_service to find the fetcher" do - substitute_fetcher = SecretFetcherImpl.new({}, nil) - expect(Chef::SecretFetcher).to receive(:for_service).with(:example, {}, nil).and_return(substitute_fetcher) - expect(substitute_fetcher).to receive(:fetch).with("key1", nil) - dsl.secret(name: "key1", service: :example, config: {}) + %w{ + secret + default_secret_service + default_secret_config + with_secret_service + with_secret_config + }.each do |m| + it "responds to ##{m}" do + expect(dsl.respond_to?(m)).to eq true + end + end + + describe "#default_secret_service" do + let(:service) { :hashi_vault } + + it "persists the service passed in as an argument" do + expect(dsl.default_secret_service).to eq(nil) + dsl.default_secret_service(service) + expect(dsl.default_secret_service).to eq(service) + end + + it "returns run_context.default_secret_service value when no argument is given" do + run_context.default_secret_service = :my_thing + expect(dsl.default_secret_service).to eq(:my_thing) + end + + it "raises exception when service given is not valid" do + stub_const("Chef::SecretFetcher::SECRET_FETCHERS", %i{service_a service_b}) + expect { dsl.default_secret_service(:unknown_service) }.to raise_error(Chef::Exceptions::Secret::InvalidFetcherService) + end end - it "resolves a secret when using the example fetcher" do - secret_value = dsl.secret(name: "test1", service: :example, config: { "test1" => "secret value" }) - expect(secret_value).to eq "secret value" + describe "#with_secret_config" do + let(:service) { :hashi_vault } + + it "sets the service for the scope of the block only" do + expect(dsl.default_secret_service).to eq(nil) + dsl.with_secret_service(service) do + expect(dsl.default_secret_service).to eq(service) + end + expect(dsl.default_secret_service).to eq(nil) + end + + it "raises exception when block is not given" do + expect { dsl.with_secret_service(service) }.to raise_error(ArgumentError) + end end - context "when used within a resource" do - let(:run_context) { - Chef::RunContext.new(Chef::Node.new, - Chef::CookbookCollection.new(Chef::CookbookLoader.new(File.join(CHEF_SPEC_DATA, "cookbooks"))), - Chef::EventDispatch::Dispatcher.new) - } - - it "marks that resource as 'sensitive'" do - recipe = Chef::Recipe.new("secrets", "test", run_context) - recipe.zen_master "secret_test" do - peace secret(name: "test1", service: :example, config: { "test1" => true }) + describe "#default_secret_config" do + let(:config) { { my_key: "value" } } + + it "persists the config passed in as argument" do + expect(dsl.default_secret_config).to eq({}) + dsl.default_secret_config(**config) + expect(dsl.default_secret_config).to eq(config) + end + + it "returns run_context.default_secret_config value when no argument is given" do + run_context.default_secret_config = { my_thing: "that" } + expect(dsl.default_secret_config).to eq({ my_thing: "that" }) + end + end + + describe "#with_secret_config" do + let(:config) { { my_key: "value" } } + + it "sets the config for the scope of the block only" do + expect(dsl.default_secret_config).to eq({}) + dsl.with_secret_config(**config) do + expect(dsl.default_secret_config).to eq(config) end - expect(run_context.resource_collection.lookup("zen_master[secret_test]").sensitive).to eql(true) + expect(dsl.default_secret_config).to eq({}) + end + + it "raises exception when block is not given" do + expect { dsl.with_secret_config(**config) }.to raise_error(ArgumentError) + end + end + + describe "#secret" do + it "uses SecretFetcher.for_service to find the fetcher" do + substitute_fetcher = SecretFetcherImpl.new({}, nil) + expect(Chef::SecretFetcher).to receive(:for_service).with(:example, {}, run_context).and_return(substitute_fetcher) + expect(substitute_fetcher).to receive(:fetch).with("key1", nil) + dsl.secret(name: "key1", service: :example, config: {}) + end + + it "resolves a secret when using the example fetcher" do + secret_value = dsl.secret(name: "test1", service: :example, config: { "test1" => "secret value" }) + expect(secret_value).to eq "secret value" + end + + context "when used within a resource" do + let(:run_context) { + Chef::RunContext.new(Chef::Node.new, + Chef::CookbookCollection.new(Chef::CookbookLoader.new(File.join(CHEF_SPEC_DATA, "cookbooks"))), + Chef::EventDispatch::Dispatcher.new) + } + + it "marks that resource as 'sensitive'" do + recipe = Chef::Recipe.new("secrets", "test", run_context) + recipe.zen_master "secret_test" do + peace secret(name: "test1", service: :example, config: { "test1" => true }) + end + expect(run_context.resource_collection.lookup("zen_master[secret_test]").sensitive).to eql(true) + end + end + + it "passes default service to SecretFetcher.for_service" do + service = :example + dsl.default_secret_service(service) + substitute_fetcher = SecretFetcherImpl.new({}, nil) + expect(Chef::SecretFetcher).to receive(:for_service).with(service, {}, run_context).and_return(substitute_fetcher) + allow(substitute_fetcher).to receive(:fetch).with("key1", nil) + dsl.secret(name: "key1") + end + + it "passes default config to SecretFetcher.for_service" do + config = { my_config: "value" } + dsl.default_secret_config(**config) + substitute_fetcher = SecretFetcherImpl.new({}, nil) + expect(Chef::SecretFetcher).to receive(:for_service).with(:example, config, run_context).and_return(substitute_fetcher) + allow(substitute_fetcher).to receive(:fetch).with("key1", nil) + dsl.secret(name: "key1", service: :example) end end end diff --git a/spec/unit/run_context_spec.rb b/spec/unit/run_context_spec.rb index 5bd7a360fb..3ec8eeed61 100644 --- a/spec/unit/run_context_spec.rb +++ b/spec/unit/run_context_spec.rb @@ -53,6 +53,22 @@ describe Chef::RunContext do expect(run_context.node).to eq(node) end + it "responds to #default_secret_service" do + expect(run_context).to respond_to(:default_secret_service) + end + + it "responds to #default_secret_config" do + expect(run_context).to respond_to(:default_secret_config) + end + + it "#default_secret_service defaults to nil" do + expect(run_context.default_secret_service).to eq(nil) + end + + it "#default_secret_config defaults to {}" do + expect(run_context.default_secret_config).to eq({}) + end + it "loads up node[:cookbooks]" do expect(run_context.node[:cookbooks]).to eql( { |