diff --git a/lib/fluent/plugin/out_s3.rb b/lib/fluent/plugin/out_s3.rb index 7db9173..c631572 100644 --- a/lib/fluent/plugin/out_s3.rb +++ b/lib/fluent/plugin/out_s3.rb @@ -62,6 +62,10 @@ def initialize config_param :duration_seconds, :integer, default: nil desc "The region of the STS endpoint to use." config_param :sts_region, :string, default: nil + desc "A http proxy url for requests to aws sts service" + config_param :sts_http_proxy, :string, default: nil, secret: true + desc "A url for a regional sts api endpoint, the default is global" + config_param :sts_endpoint_url, :string, default: nil end config_section :instance_profile_credentials, multi: false do desc "Number of times to retry when retrieving credentials" @@ -540,15 +544,22 @@ def setup_credentials options[:secret_access_key] = @aws_sec_key when @web_identity_credentials c = @web_identity_credentials + region = c.sts_region || @s3_region credentials_options[:role_arn] = c.role_arn credentials_options[:role_session_name] = c.role_session_name credentials_options[:web_identity_token_file] = c.web_identity_token_file credentials_options[:policy] = c.policy if c.policy credentials_options[:duration_seconds] = c.duration_seconds if c.duration_seconds - if c.sts_region - credentials_options[:client] = Aws::STS::Client.new(:region => c.sts_region) - elsif @s3_region - credentials_options[:client] = Aws::STS::Client.new(:region => @s3_region) + credentials_options[:sts_endpoint_url] = c.sts_endpoint_url if c.sts_endpoint_url + credentials_options[:sts_http_proxy] = c.sts_http_proxy if c.sts_http_proxy + if c.sts_http_proxy && c.sts_endpoint_url + credentials_options[:client] = Aws::STS::Client.new(region: region, http_proxy: c.sts_http_proxy, endpoint: c.sts_endpoint_url) + elsif c.sts_http_proxy + credentials_options[:client] = Aws::STS::Client.new(region: region, http_proxy: c.sts_http_proxy) + elsif c.sts_endpoint_url + credentials_options[:client] = Aws::STS::Client.new(region: region, endpoint: c.sts_endpoint_url) + else + credentials_options[:client] = Aws::STS::Client.new(region: region) end options[:credentials] = Aws::AssumeRoleWebIdentityCredentials.new(credentials_options) when @instance_profile_credentials diff --git a/test/test_out_s3.rb b/test/test_out_s3.rb index 2d7941d..fbb2945 100644 --- a/test/test_out_s3.rb +++ b/test/test_out_s3.rb @@ -803,6 +803,92 @@ def test_web_identity_credentials assert_equal(expected_credentials, credentials) end + def test_web_identity_credentials_with_region_and_sts_http_proxy + expected_credentials = Aws::Credentials.new("test_key", "test_secret") + expected_region = "ap-northeast-1" + expected_sts_http_proxy = 'http://example.com' + sts_client = Aws::STS::Client.new(region: expected_region, http_proxy: expected_sts_http_proxy) + mock(Aws::STS::Client).new(region:expected_region, http_proxy: expected_sts_http_proxy){ sts_client } + mock(Aws::AssumeRoleWebIdentityCredentials).new({ role_arn: "test_arn", + role_session_name: "test_session", + web_identity_token_file: "test_file", + client: sts_client, + sts_http_proxy: expected_sts_http_proxy }){ + expected_credentials + } + config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n") + config += %[ + s3_region #{expected_region} + + role_arn test_arn + role_session_name test_session + web_identity_token_file test_file + sts_http_proxy #{expected_sts_http_proxy} + + ] + d = create_time_sliced_driver(config) + assert_nothing_raised { d.run {} } + client = d.instance.instance_variable_get(:@s3).client + credentials = client.config.credentials + assert_equal(expected_credentials, credentials) + end + + def test_web_identity_credentials_with_sts_http_proxy + expected_credentials = Aws::Credentials.new("test_key", "test_secret") + expected_sts_http_proxy = 'http://example.com' + sts_client = Aws::STS::Client.new(region: "us-east-1", http_proxy: expected_sts_http_proxy) + mock(Aws::STS::Client).new(region: "us-east-1", http_proxy: expected_sts_http_proxy){ sts_client } + mock(Aws::AssumeRoleWebIdentityCredentials).new({ role_arn: "test_arn", + role_session_name: "test_session", + web_identity_token_file: "test_file", + client: sts_client, + sts_http_proxy: expected_sts_http_proxy }){ + expected_credentials + } + config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n") + config += %[ + + role_arn test_arn + role_session_name test_session + web_identity_token_file test_file + sts_http_proxy #{expected_sts_http_proxy} + + ] + d = create_time_sliced_driver(config) + assert_nothing_raised { d.run {} } + client = d.instance.instance_variable_get(:@s3).client + credentials = client.config.credentials + assert_equal(expected_credentials, credentials) + end + + def test_web_identity_credentials_with_sts_endpoint_url + expected_credentials = Aws::Credentials.new("test_key", "test_secret") + expected_sts_endpoint_url = 'http://example.com' + sts_client = Aws::STS::Client.new(region: "us-east-1", endpoint: expected_sts_endpoint_url) + mock(Aws::STS::Client).new(region: "us-east-1", endpoint: expected_sts_endpoint_url){ sts_client } + mock(Aws::AssumeRoleWebIdentityCredentials).new({ role_arn: "test_arn", + role_session_name: "test_session", + web_identity_token_file: "test_file", + client: sts_client, + sts_endpoint_url: expected_sts_endpoint_url }){ + expected_credentials + } + config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n") + config += %[ + + role_arn test_arn + role_session_name test_session + web_identity_token_file test_file + sts_endpoint_url #{expected_sts_endpoint_url} + + ] + d = create_time_sliced_driver(config) + assert_nothing_raised { d.run {} } + client = d.instance.instance_variable_get(:@s3).client + credentials = client.config.credentials + assert_equal(expected_credentials, credentials) + end + def test_web_identity_credentials_with_sts_region expected_credentials = Aws::Credentials.new("test_key", "test_secret") sts_client = Aws::STS::Client.new(region: 'us-east-1')