diff --git a/lib/fog/aws/credential_fetcher.rb b/lib/fog/aws/credential_fetcher.rb index bc397cb4c..c39fd3b11 100644 --- a/lib/fog/aws/credential_fetcher.rb +++ b/lib/fog/aws/credential_fetcher.rb @@ -29,6 +29,17 @@ def fetch_credentials(options) role_data = connection.get(:path => credential_path, :idempotent => true, :expects => 200).body session = Fog::JSON.decode(role_data) + if region.nil? + connection = options[:metadata_connection] || Excon.new(INSTANCE_METADATA_HOST) + token_header = fetch_credentials_token_header(connection, options[:disable_imds_v2]) + region = connection.get(:path => INSTANCE_METADATA_AZ, :idempotent => true, :expects => 200, :headers => token_header).body[0..-2] + end + elsif ENV["AWS_CONTAINER_CREDENTIALS_FULL_URI"] + connection = options[:connection] || Excon.new(ENV['AWS_CONTAINER_CREDENTIALS_FULL_URI']) + container_authorization_token = File.read(options[:aws_container_authorization_token_file] || ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE']) + role_data = connection.get(:idempotent => true, :expects => 200, :headers => {'Authorization' => container_authorization_token}).body + session = Fog::JSON.decode(role_data) + if region.nil? connection = options[:metadata_connection] || Excon.new(INSTANCE_METADATA_HOST) token_header = fetch_credentials_token_header(connection, options[:disable_imds_v2]) diff --git a/tests/credentials_tests.rb b/tests/credentials_tests.rb index e7bcea39f..e40722f8c 100644 --- a/tests/credentials_tests.rb +++ b/tests/credentials_tests.rb @@ -85,6 +85,30 @@ ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'] = nil + # Make sure fetched credentials are different from those of instance metadata endpoint + container_credentials = { + 'AccessKeyId' => 'dummycontainerkey', + 'SecretAccessKey' => 'dummycontainersecret', + 'Token' => 'dummycontainertoken', + 'Expiration' => expires_at.xmlschema + } + + ENV['AWS_CONTAINER_CREDENTIALS_FULL_URI'] = 'http://169.254.170.23/v1/credentials' + ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE'] = File.dirname(__FILE__) + '/lorem.txt' + Excon.stub({ method: :get, scheme: 'http', host: '169.254.170.23', path: '/v1/credentials' }, + { status: 200, body: Fog::JSON.encode(container_credentials) }) + + tests('#fetch_credentials with EKS Pod Identity') do + returns(aws_access_key_id: 'dummycontainerkey', + aws_secret_access_key: 'dummycontainersecret', + aws_session_token: 'dummycontainertoken', + region: 'us-west-1', + aws_credentials_expire_at: expires_at) { Fog::AWS::Compute.fetch_credentials(use_iam_profile: true) } + end + + ENV['AWS_CONTAINER_CREDENTIALS_FULL_URI'] = nil + ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE'] = nil + ENV['AWS_WEB_IDENTITY_TOKEN_FILE'] = File.dirname(__FILE__) + '/lorem.txt' ENV['AWS_ROLE_ARN'] = "dummyrole" ENV['AWS_ROLE_SESSION_NAME'] = "dummyrolesessionname" @@ -259,6 +283,8 @@ end ensure ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI'] = nil + ENV['AWS_CONTAINER_CREDENTIALS_FULL_URI'] = nil + ENV['AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE'] = nil ENV['AWS_WEB_IDENTITY_TOKEN_FILE'] = nil Excon.stubs.clear Excon.defaults[:mock] = old_mock_value