diff options
author | Marc A. Paradise <marc.paradise@gmail.com> | 2021-07-22 16:33:35 -0400 |
---|---|---|
committer | Marc A. Paradise <marc.paradise@gmail.com> | 2021-07-26 17:41:13 -0400 |
commit | 1ce6fa2fae940a19a3604c10ef8316c0dc2568eb (patch) | |
tree | 79995642a99d75657b1ec9430044b49f2a50c4bc | |
parent | 8c1c3f4767368e629268b89bf5b71a827bd12b5d (diff) | |
download | chef-1ce6fa2fae940a19a3604c10ef8316c0dc2568eb.tar.gz |
secrets: aws fetcher uses node attributes for region
When region is not specified and is not in AWS global configuration,
we'll now default to the region in `node["ec2"]["region"]`; and we will
fail if that is also not provided.
This provides a sane and predictable way to play nicely with AWS SDK's
default config loading behavior.
Signed-off-by: Marc A. Paradise <marc.paradise@gmail.com>
-rw-r--r-- | lib/chef/secret_fetcher/aws_secrets_manager.rb | 20 | ||||
-rw-r--r-- | spec/unit/secret_fetcher/aws_secrets_manager_spec.rb | 70 |
2 files changed, 86 insertions, 4 deletions
diff --git a/lib/chef/secret_fetcher/aws_secrets_manager.rb b/lib/chef/secret_fetcher/aws_secrets_manager.rb index 3619a37dd0..c7b6b52b45 100644 --- a/lib/chef/secret_fetcher/aws_secrets_manager.rb +++ b/lib/chef/secret_fetcher/aws_secrets_manager.rb @@ -17,6 +17,7 @@ # require_relative "base" +require "aws-sdk-core" require "aws-sdk-secretsmanager" class Chef @@ -26,19 +27,30 @@ class Chef # It is possible to pass options that configure it to use alternative credentials. # This implementation supports fetching with version. # - # NOTE: This does not yet support automatic retries, which the AWS client does by default. + # @note ':region' is required configuration. If it is not explicitly provided, + # and it is not available via global AWS config, we will pull it from node ohai data by default. + # If this isn't correct, you will need to explicitly override it. + # If it is not available via ohai data either (such as if you have the AWS plugin disabled) + # then the converge will fail with an error. + # + # @note: This does not yet support automatic retries, which the AWS client does by default. # # For configuration options see https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/SecretsManager/Client.html#initialize-instance_method # - # Note that ~/.aws default and environment-based configurations are supported by default in the - # ruby SDK. # # Usage Example: # - # fetcher = SecretFetcher.for_service(:aws_secrets_manager, { region: "us-east-1" }) + # fetcher = SecretFetcher.for_service(:aws_secrets_manager) # fetcher.fetch("secretkey1", "v1") class SecretFetcher class AWSSecretsManager < Base + def validate! + config[:region] = config[:region] || Aws.config[:region] || run_context.node.dig("ec2", "region") + if config[:region].nil? + raise Chef::Exceptions::Secret::ConfigurationInvalid.new("Missing required config for AWS secret fetcher: :region") + end + end + # @param identifier [String] the secret_id # @param version [String] the secret version. Not usd at this time # @return Aws::SecretsManager::Types::GetSecretValueResponse diff --git a/spec/unit/secret_fetcher/aws_secrets_manager_spec.rb b/spec/unit/secret_fetcher/aws_secrets_manager_spec.rb new file mode 100644 index 0000000000..a98813a7bc --- /dev/null +++ b/spec/unit/secret_fetcher/aws_secrets_manager_spec.rb @@ -0,0 +1,70 @@ +# +# Author:: Marc Paradise <marc@chef.io> +# Copyright:: Copyright (c) Chef Software Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +require_relative "../../spec_helper" +require "chef/secret_fetcher/aws_secrets_manager" + +describe Chef::SecretFetcher::AWSSecretsManager do + let(:node) { {} } + let(:aws_global_config) { {} } + let(:fetcher_config) { {} } + let(:run_context) { double("run_context", node: node) } + let(:fetcher) { + Chef::SecretFetcher::AWSSecretsManager.new( fetcher_config, run_context ) + } + + before do + allow(Aws).to receive(:config).and_return(aws_global_config) + end + + context "when region is provided" do + let(:fetcher_config) { { region: "region-from-caller" } } + it "uses the provided region" do + fetcher.validate! + expect(fetcher.config[:region]).to eq "region-from-caller" + end + end + + context "when region is not provided" do + context "and no region exists in AWS config or node attributes" do + it "raises a ConfigurationInvalid error" do + expect { fetcher.validate! }.to raise_error Chef::Exceptions::Secret::ConfigurationInvalid + end + end + + context "and region exists in AWS config and node attributes" do + let(:aws_global_config) { { region: "region-from-aws-global-config" } } + let(:node) { { "ec2" => { "region" => "region-from-ohai-data" } } } + it "uses the region from AWS config" do + fetcher.validate! + expect(fetcher.config[:region]).to eq "region-from-aws-global-config" + end + end + + context "and region exists only in node attributes" do + let(:node) { { "ec2" => { "region" => "region-from-ohai-data" } } } + it "uses the region from AWS config" do + fetcher.validate! + expect(fetcher.config[:region]).to eq "region-from-ohai-data" + end + + end + + end +end |