@@ -16,6 +16,7 @@ import (
16
16
"time"
17
17
18
18
"github.com/aws/aws-sdk-go-v2/aws"
19
+ "github.com/aws/aws-sdk-go-v2/credentials/ec2rolecreds"
19
20
"github.com/aws/aws-sdk-go-v2/feature/ec2/imds"
20
21
"github.com/aws/aws-sdk-go-v2/internal/awstesting"
21
22
"github.com/aws/aws-sdk-go-v2/service/sso"
@@ -82,9 +83,15 @@ func setupCredentialsEndpoints() (aws.EndpointResolverWithOptions, func()) {
82
83
83
84
ec2MetadataServer := httptest .NewServer (http .HandlerFunc (
84
85
func (w http.ResponseWriter , r * http.Request ) {
85
- if r .URL .Path == "/latest/meta-data/iam/security-credentials/RoleName" {
86
+ if r .URL .Path == "/latest/meta-data/iam/security-credentials-extended /RoleName" {
86
87
w .Write ([]byte (ec2MetadataResponse ))
87
- } else if r .URL .Path == "/latest/meta-data/iam/security-credentials/" {
88
+ } else if r .URL .Path == "/latest/meta-data/iam/security-credentials-extended/LoadOptions" {
89
+ w .Write ([]byte (ec2MetadataResponseLoadOptions ))
90
+ } else if r .URL .Path == "/latest/meta-data/iam/security-credentials-extended/EnvCfg" {
91
+ w .Write ([]byte (ec2MetadataResponseEnvCfg ))
92
+ } else if r .URL .Path == "/latest/meta-data/iam/security-credentials-extended/SharedCfg" {
93
+ w .Write ([]byte (ec2MetadataResponseSharedCfg ))
94
+ } else if r .URL .Path == "/latest/meta-data/iam/security-credentials-extended/" {
88
95
w .Write ([]byte ("RoleName" ))
89
96
} else if r .URL .Path == "/latest/api/token" {
90
97
header := w .Header ()
@@ -750,6 +757,103 @@ func TestResolveCredentialsEcsContainer(t *testing.T) {
750
757
751
758
}
752
759
760
+ func TestResolveCredentialsEC2RoleCreds (t * testing.T ) {
761
+ testCases := map [string ]struct {
762
+ expectedAccessKey string
763
+ expectedSecretKey string
764
+ envVar map [string ]string
765
+ configFile string
766
+ configProfile string
767
+ loadOptions func (* LoadOptions ) error
768
+ }{
769
+ "no config whatsoever" : {
770
+ expectedAccessKey : "ec2-access-key" ,
771
+ expectedSecretKey : "ec2-secret-key" ,
772
+ envVar : map [string ]string {},
773
+ configFile : "" ,
774
+ },
775
+ "env cfg" : {
776
+ expectedAccessKey : "ec2-access-key-envcfg" ,
777
+ expectedSecretKey : "ec2-secret-key-envcfg" ,
778
+ envVar : map [string ]string {
779
+ "AWS_EC2_INSTANCE_PROFILE_NAME" : "EnvCfg" ,
780
+ },
781
+ configFile : "" ,
782
+ },
783
+ "shared cfg" : {
784
+ expectedAccessKey : "ec2-access-key-sharedcfg" ,
785
+ expectedSecretKey : "ec2-secret-key-sharedcfg" ,
786
+ envVar : map [string ]string {},
787
+ configFile : filepath .Join ("testdata" , "config_source_shared" ),
788
+ configProfile : "ec2metadata-profilename" ,
789
+ },
790
+ "loadopts + env cfg + shared cfg" : {
791
+ expectedAccessKey : "ec2-access-key-loadopts" ,
792
+ expectedSecretKey : "ec2-secret-key-loadopts" ,
793
+ envVar : map [string ]string {
794
+ "AWS_EC2_INSTANCE_PROFILE_NAME" : "EnvCfg" ,
795
+ },
796
+ configFile : filepath .Join ("testdata" , "config_source_shared" ),
797
+ configProfile : "ec2metadata-profilename" ,
798
+ loadOptions : WithEC2RoleCredentialOptions (func (o * ec2rolecreds.Options ) {
799
+ o .ProfileName = "LoadOptions"
800
+ }),
801
+ },
802
+ }
803
+
804
+ for name , tc := range testCases {
805
+ t .Run (name , func (t * testing.T ) {
806
+ endpointResolver , cleanupFn := setupCredentialsEndpoints ()
807
+ defer cleanupFn ()
808
+
809
+ // setupCredentialsEndpoints sets this above and then we hold onto
810
+ // it for this test
811
+ ec2MetadataURL := os .Getenv ("AWS_EC2_METADATA_SERVICE_ENDPOINT" )
812
+
813
+ restoreEnv := awstesting .StashEnv ()
814
+ defer awstesting .PopEnv (restoreEnv )
815
+
816
+ os .Setenv ("AWS_EC2_METADATA_SERVICE_ENDPOINT" , ec2MetadataURL )
817
+ for k , v := range tc .envVar {
818
+ os .Setenv (k , v )
819
+ }
820
+ var sharedConfigFiles []string
821
+ if tc .configFile != "" {
822
+ sharedConfigFiles = append (sharedConfigFiles , tc .configFile )
823
+ }
824
+ opts := []func (* LoadOptions ) error {
825
+ WithEndpointResolverWithOptions (endpointResolver ),
826
+ WithRetryer (func () aws.Retryer { return aws.NopRetryer {} }),
827
+ WithSharedConfigFiles (sharedConfigFiles ),
828
+ WithSharedCredentialsFiles ([]string {}),
829
+ }
830
+ if len (tc .configProfile ) != 0 {
831
+ opts = append (opts , WithSharedConfigProfile (tc .configProfile ))
832
+ }
833
+
834
+ if tc .loadOptions != nil {
835
+ opts = append (opts , tc .loadOptions )
836
+ }
837
+
838
+ cfg , err := LoadDefaultConfig (context .TODO (), opts ... )
839
+ if err != nil {
840
+ t .Fatalf ("could not load config: %s" , err )
841
+ }
842
+ actual , err := cfg .Credentials .Retrieve (context .TODO ())
843
+ if err != nil {
844
+ t .Fatalf ("could not retrieve credentials: %s" , err )
845
+ }
846
+ if actual .AccessKeyID != tc .expectedAccessKey {
847
+ t .Errorf ("expected access key to be %s, got %s" , tc .expectedAccessKey , actual .AccessKeyID )
848
+ }
849
+ if actual .SecretAccessKey != tc .expectedSecretKey {
850
+ t .Errorf ("expected secret key to be %s, got %s" , tc .expectedSecretKey , actual .SecretAccessKey )
851
+ }
852
+ })
853
+ }
854
+
855
+ }
856
+
753
857
type stubErrorClient struct {
754
858
err error
755
859
}
0 commit comments