summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc A. Paradise <marc.paradise@gmail.com>2021-07-22 16:33:35 -0400
committerMarc A. Paradise <marc.paradise@gmail.com>2021-07-26 17:41:13 -0400
commit1ce6fa2fae940a19a3604c10ef8316c0dc2568eb (patch)
tree79995642a99d75657b1ec9430044b49f2a50c4bc
parent8c1c3f4767368e629268b89bf5b71a827bd12b5d (diff)
downloadchef-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.rb20
-rw-r--r--spec/unit/secret_fetcher/aws_secrets_manager_spec.rb70
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