summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorLamont Granquist <454857+lamont-granquist@users.noreply.github.com>2022-03-29 13:04:03 -0700
committerGitHub <noreply@github.com>2022-03-29 13:04:03 -0700
commit2a33d348eedad45e8416a7487eb13fac337bdcfc (patch)
treee5ae17f909bf39872c161ac08f50ef34d3274490 /spec
parent20db13b428afd1975e4049ba7c8f5ee1645217bf (diff)
parentff68fd07a9fbcd5a7de89b30d3669819c4af8ed7 (diff)
downloadchef-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.rb150
-rw-r--r--spec/unit/run_context_spec.rb16
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(
{