Skip to content

Commit d0cf123

Browse files
committed
Use IAM API credentials when assuming a role. Fixes #330
Signed-off-by: Jarosław Śmiejczak <[email protected]>
1 parent f957b40 commit d0cf123

File tree

3 files changed

+144
-15
lines changed

3 files changed

+144
-15
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ gemfile:
1313
branches:
1414
only:
1515
- master
16+
- test-fix
1617

1718
before_install: gem update bundler
1819
script: bundle exec rake test

lib/fluent/plugin/out_s3.rb

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -473,11 +473,10 @@ def setup_credentials
473473
options = {}
474474
credentials_options = {}
475475
case
476-
when @aws_key_id && @aws_sec_key
477-
options[:access_key_id] = @aws_key_id
478-
options[:secret_access_key] = @aws_sec_key
479476
when @assume_role_credentials
480477
c = @assume_role_credentials
478+
iam_user_credentials = @aws_key_id && @aws_sec_key ? Aws::Credentials.new(@aws_key_id, @aws_sec_key) : nil
479+
region = c.sts_region || @s3_region
481480
credentials_options[:role_arn] = c.role_arn
482481
credentials_options[:role_session_name] = c.role_session_name
483482
credentials_options[:policy] = c.policy if c.policy
@@ -486,21 +485,19 @@ def setup_credentials
486485
credentials_options[:sts_endpoint_url] = c.sts_endpoint_url if c.sts_endpoint_url
487486
credentials_options[:sts_http_proxy] = c.sts_http_proxy if c.sts_http_proxy
488487
if c.sts_http_proxy && c.sts_endpoint_url
489-
credentials_options[:client] = Aws::STS::Client.new(http_proxy: c.sts_http_proxy, endpoint: c.sts_endpoint_url)
490-
elsif @region && c.sts_http_proxy
491-
credentials_options[:client] = Aws::STS::Client.new(region: @region, http_proxy: c.sts_http_proxy)
492-
elsif @region && c.sts_endpoint_url
493-
credentials_options[:client] = Aws::STS::Client.new(region: @region, endpoint: c.sts_endpoint_url)
488+
credentials_options[:client] = Aws::STS::Client.new(region: region, http_proxy: c.sts_http_proxy, endpoint: c.sts_endpoint_url, credentials: iam_user_credentials)
494489
elsif c.sts_http_proxy
495-
credentials_options[:client] = Aws::STS::Client.new(http_proxy: c.sts_http_proxy)
490+
credentials_options[:client] = Aws::STS::Client.new(region: region, http_proxy: c.sts_http_proxy, credentials: iam_user_credentials)
496491
elsif c.sts_endpoint_url
497-
credentials_options[:client] = Aws::STS::Client.new(endpoint: c.sts_endpoint_url)
498-
elsif c.sts_region
499-
credentials_options[:client] = Aws::STS::Client.new(region: c.sts_region)
500-
elsif @s3_region
501-
credentials_options[:client] = Aws::STS::Client.new(region: @s3_region)
492+
credentials_options[:client] = Aws::STS::Client.new(region: region, endpoint: c.sts_endpoint_url, credentials: iam_user_credentials)
493+
else
494+
credentials_options[:client] = Aws::STS::Client.new(region: region, credentials: iam_user_credentials)
502495
end
496+
503497
options[:credentials] = Aws::AssumeRoleCredentials.new(credentials_options)
498+
when @aws_key_id && @aws_sec_key
499+
options[:access_key_id] = @aws_key_id
500+
options[:secret_access_key] = @aws_sec_key
504501
when @web_identity_credentials
505502
c = @web_identity_credentials
506503
credentials_options[:role_arn] = c.role_arn

test/test_out_s3.rb

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,7 @@ def test_assume_role_credentials
539539
def test_assume_role_credentials_with_region
540540
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
541541
sts_client = Aws::STS::Client.new(region: 'ap-northeast-1')
542-
mock(Aws::STS::Client).new(region: 'ap-northeast-1'){ sts_client }
542+
mock(Aws::STS::Client).new(region: 'ap-northeast-1', credentials: nil){ sts_client }
543543
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
544544
role_session_name: "test_session",
545545
client: sts_client){
@@ -560,6 +560,137 @@ def test_assume_role_credentials_with_region
560560
assert_equal(expected_credentials, credentials)
561561
end
562562

563+
def test_assume_role_with_iam_credentials
564+
expected_credentials = Aws::Credentials.new("test_key_id", "test_sec_key")
565+
sts_client = Aws::STS::Client.new(region: 'ap-northeast-1', credentials: expected_credentials)
566+
mock(Aws::Credentials).new("test_key_id", "test_sec_key") { expected_credentials }
567+
mock(Aws::STS::Client).new(region: 'ap-northeast-1', credentials: expected_credentials){ sts_client }
568+
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
569+
role_session_name: "test_session",
570+
client: sts_client){
571+
expected_credentials
572+
}
573+
config = CONFIG_TIME_SLICE
574+
config += %[
575+
s3_region ap-northeast-1
576+
577+
<assume_role_credentials>
578+
role_arn test_arn
579+
role_session_name test_session
580+
</assume_role_credentials>
581+
]
582+
d = create_time_sliced_driver(config)
583+
assert_nothing_raised { d.run {} }
584+
client = d.instance.instance_variable_get(:@s3).client
585+
credentials = client.config.credentials
586+
assert_equal(expected_credentials, credentials)
587+
end
588+
589+
def test_assume_role_credentials_with_region_and_sts_http_proxy
590+
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
591+
expected_region = "ap-northeast-1"
592+
expected_sts_http_proxy = 'http://example.com'
593+
sts_client = Aws::STS::Client.new(region: expected_region, http_proxy: expected_sts_http_proxy)
594+
mock(Aws::STS::Client).new(region:expected_region, http_proxy: expected_sts_http_proxy, credentials: nil){ sts_client }
595+
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
596+
role_session_name: "test_session",
597+
client: sts_client,
598+
sts_http_proxy: expected_sts_http_proxy){
599+
expected_credentials
600+
}
601+
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
602+
config += %[
603+
s3_region #{expected_region}
604+
<assume_role_credentials>
605+
role_arn test_arn
606+
role_session_name test_session
607+
sts_http_proxy #{expected_sts_http_proxy}
608+
</assume_role_credentials>
609+
]
610+
d = create_time_sliced_driver(config)
611+
assert_nothing_raised { d.run {} }
612+
client = d.instance.instance_variable_get(:@s3).client
613+
credentials = client.config.credentials
614+
assert_equal(expected_credentials, credentials)
615+
end
616+
617+
def test_assume_role_credentials_with_sts_http_proxy
618+
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
619+
expected_sts_http_proxy = 'http://example.com'
620+
sts_client = Aws::STS::Client.new(region: "us-east-1", http_proxy: expected_sts_http_proxy)
621+
mock(Aws::STS::Client).new(region: "us-east-1", http_proxy: expected_sts_http_proxy, credentials: nil){ sts_client }
622+
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
623+
role_session_name: "test_session",
624+
client: sts_client,
625+
sts_http_proxy: expected_sts_http_proxy){
626+
expected_credentials
627+
}
628+
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
629+
config += %[
630+
<assume_role_credentials>
631+
role_arn test_arn
632+
role_session_name test_session
633+
sts_http_proxy #{expected_sts_http_proxy}
634+
</assume_role_credentials>
635+
]
636+
d = create_time_sliced_driver(config)
637+
assert_nothing_raised { d.run {} }
638+
client = d.instance.instance_variable_get(:@s3).client
639+
credentials = client.config.credentials
640+
assert_equal(expected_credentials, credentials)
641+
end
642+
643+
def test_assume_role_credentials_with_sts_endpoint_url
644+
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
645+
expected_sts_endpoint_url = 'http://example.com'
646+
sts_client = Aws::STS::Client.new(region: "us-east-1", endpoint: expected_sts_endpoint_url)
647+
mock(Aws::STS::Client).new(region: "us-east-1", endpoint: expected_sts_endpoint_url, credentials: nil){ sts_client }
648+
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
649+
role_session_name: "test_session",
650+
client: sts_client,
651+
sts_endpoint_url: expected_sts_endpoint_url){
652+
expected_credentials
653+
}
654+
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
655+
config += %[
656+
<assume_role_credentials>
657+
role_arn test_arn
658+
role_session_name test_session
659+
sts_endpoint_url #{expected_sts_endpoint_url}
660+
</assume_role_credentials>
661+
]
662+
d = create_time_sliced_driver(config)
663+
assert_nothing_raised { d.run {} }
664+
client = d.instance.instance_variable_get(:@s3).client
665+
credentials = client.config.credentials
666+
assert_equal(expected_credentials, credentials)
667+
end
668+
669+
def test_assume_role_credentials_with_sts_region
670+
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
671+
expected_sts_region = 'ap-south-1'
672+
sts_client = Aws::STS::Client.new(region: expected_sts_region)
673+
mock(Aws::STS::Client).new(region: expected_sts_region, credentials: nil){ sts_client }
674+
mock(Aws::AssumeRoleCredentials).new(role_arn: "test_arn",
675+
role_session_name: "test_session",
676+
client: sts_client){
677+
expected_credentials
678+
}
679+
config = CONFIG_TIME_SLICE.split("\n").reject{|x| x =~ /.+aws_.+/}.join("\n")
680+
config += %[
681+
<assume_role_credentials>
682+
role_arn test_arn
683+
role_session_name test_session
684+
sts_region #{expected_sts_region}
685+
</assume_role_credentials>
686+
]
687+
d = create_time_sliced_driver(config)
688+
assert_nothing_raised { d.run {} }
689+
client = d.instance.instance_variable_get(:@s3).client
690+
credentials = client.config.credentials
691+
assert_equal(expected_credentials, credentials)
692+
end
693+
563694
def test_web_identity_credentials
564695
expected_credentials = Aws::Credentials.new("test_key", "test_secret")
565696
mock(Aws::AssumeRoleWebIdentityCredentials).new(

0 commit comments

Comments
 (0)