github.com/aavshr/aws-sdk-go@v1.41.3/aws/session/shared_config_test.go (about)

     1  //go:build go1.7
     2  // +build go1.7
     3  
     4  package session
     5  
     6  import (
     7  	"fmt"
     8  	"path/filepath"
     9  	"reflect"
    10  	"strconv"
    11  	"strings"
    12  	"testing"
    13  
    14  	"github.com/aavshr/aws-sdk-go/aws/credentials"
    15  	"github.com/aavshr/aws-sdk-go/aws/endpoints"
    16  	"github.com/aavshr/aws-sdk-go/internal/ini"
    17  )
    18  
    19  var (
    20  	testConfigFilename      = filepath.Join("testdata", "shared_config")
    21  	testConfigOtherFilename = filepath.Join("testdata", "shared_config_other")
    22  )
    23  
    24  func TestLoadSharedConfig(t *testing.T) {
    25  	cases := []struct {
    26  		Filenames []string
    27  		Profile   string
    28  		Expected  sharedConfig
    29  		Err       error
    30  	}{
    31  		{
    32  			Filenames: []string{"file_not_exists"},
    33  			Profile:   "default",
    34  			Expected: sharedConfig{
    35  				Profile: "default",
    36  			},
    37  		},
    38  		{
    39  			Filenames: []string{testConfigFilename},
    40  			Expected: sharedConfig{
    41  				Profile: "default",
    42  				Region:  "default_region",
    43  			},
    44  		},
    45  		{
    46  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
    47  			Profile:   "config_file_load_order",
    48  			Expected: sharedConfig{
    49  				Profile: "config_file_load_order",
    50  				Region:  "shared_config_region",
    51  				Creds: credentials.Value{
    52  					AccessKeyID:     "shared_config_akid",
    53  					SecretAccessKey: "shared_config_secret",
    54  					ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
    55  				},
    56  			},
    57  		},
    58  		{
    59  			Filenames: []string{testConfigFilename, testConfigOtherFilename},
    60  			Profile:   "config_file_load_order",
    61  			Expected: sharedConfig{
    62  				Profile: "config_file_load_order",
    63  				Region:  "shared_config_other_region",
    64  				Creds: credentials.Value{
    65  					AccessKeyID:     "shared_config_other_akid",
    66  					SecretAccessKey: "shared_config_other_secret",
    67  					ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigOtherFilename),
    68  				},
    69  			},
    70  		},
    71  		{
    72  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
    73  			Profile:   "assume_role",
    74  			Expected: sharedConfig{
    75  				Profile:           "assume_role",
    76  				RoleARN:           "assume_role_role_arn",
    77  				SourceProfileName: "complete_creds",
    78  				SourceProfile: &sharedConfig{
    79  					Profile: "complete_creds",
    80  					Creds: credentials.Value{
    81  						AccessKeyID:     "complete_creds_akid",
    82  						SecretAccessKey: "complete_creds_secret",
    83  						ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
    84  					},
    85  				},
    86  			},
    87  		},
    88  		{
    89  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
    90  			Profile:   "assume_role_invalid_source_profile",
    91  			Expected: sharedConfig{
    92  				Profile:           "assume_role_invalid_source_profile",
    93  				RoleARN:           "assume_role_invalid_source_profile_role_arn",
    94  				SourceProfileName: "profile_not_exists",
    95  			},
    96  			Err: SharedConfigAssumeRoleError{
    97  				RoleARN:       "assume_role_invalid_source_profile_role_arn",
    98  				SourceProfile: "profile_not_exists",
    99  			},
   100  		},
   101  		{
   102  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
   103  			Profile:   "assume_role_w_creds",
   104  			Expected: sharedConfig{
   105  				Profile:           "assume_role_w_creds",
   106  				RoleARN:           "assume_role_w_creds_role_arn",
   107  				ExternalID:        "1234",
   108  				RoleSessionName:   "assume_role_w_creds_session_name",
   109  				SourceProfileName: "assume_role_w_creds",
   110  				SourceProfile: &sharedConfig{
   111  					Profile: "assume_role_w_creds",
   112  					Creds: credentials.Value{
   113  						AccessKeyID:     "assume_role_w_creds_akid",
   114  						SecretAccessKey: "assume_role_w_creds_secret",
   115  						ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
   116  					},
   117  				},
   118  			},
   119  		},
   120  		{
   121  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
   122  			Profile:   "assume_role_wo_creds",
   123  			Expected: sharedConfig{
   124  				Profile:           "assume_role_wo_creds",
   125  				RoleARN:           "assume_role_wo_creds_role_arn",
   126  				SourceProfileName: "assume_role_wo_creds",
   127  			},
   128  			Err: SharedConfigAssumeRoleError{
   129  				RoleARN:       "assume_role_wo_creds_role_arn",
   130  				SourceProfile: "assume_role_wo_creds",
   131  			},
   132  		},
   133  		{
   134  			Filenames: []string{filepath.Join("testdata", "shared_config_invalid_ini")},
   135  			Profile:   "profile_name",
   136  			Err:       SharedConfigLoadError{Filename: filepath.Join("testdata", "shared_config_invalid_ini")},
   137  		},
   138  		{
   139  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
   140  			Profile:   "assume_role_with_credential_source",
   141  			Expected: sharedConfig{
   142  				Profile:          "assume_role_with_credential_source",
   143  				RoleARN:          "assume_role_with_credential_source_role_arn",
   144  				CredentialSource: credSourceEc2Metadata,
   145  			},
   146  		},
   147  		{
   148  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
   149  			Profile:   "multiple_assume_role",
   150  			Expected: sharedConfig{
   151  				Profile:           "multiple_assume_role",
   152  				RoleARN:           "multiple_assume_role_role_arn",
   153  				SourceProfileName: "assume_role",
   154  				SourceProfile: &sharedConfig{
   155  					Profile:           "assume_role",
   156  					RoleARN:           "assume_role_role_arn",
   157  					SourceProfileName: "complete_creds",
   158  					SourceProfile: &sharedConfig{
   159  						Profile: "complete_creds",
   160  						Creds: credentials.Value{
   161  							AccessKeyID:     "complete_creds_akid",
   162  							SecretAccessKey: "complete_creds_secret",
   163  							ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
   164  						},
   165  					},
   166  				},
   167  			},
   168  		},
   169  		{
   170  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
   171  			Profile:   "multiple_assume_role_with_credential_source",
   172  			Expected: sharedConfig{
   173  				Profile:           "multiple_assume_role_with_credential_source",
   174  				RoleARN:           "multiple_assume_role_with_credential_source_role_arn",
   175  				SourceProfileName: "assume_role_with_credential_source",
   176  				SourceProfile: &sharedConfig{
   177  					Profile:          "assume_role_with_credential_source",
   178  					RoleARN:          "assume_role_with_credential_source_role_arn",
   179  					CredentialSource: credSourceEc2Metadata,
   180  				},
   181  			},
   182  		},
   183  		{
   184  			Filenames: []string{testConfigOtherFilename, testConfigFilename},
   185  			Profile:   "multiple_assume_role_with_credential_source2",
   186  			Expected: sharedConfig{
   187  				Profile:           "multiple_assume_role_with_credential_source2",
   188  				RoleARN:           "multiple_assume_role_with_credential_source2_role_arn",
   189  				SourceProfileName: "multiple_assume_role_with_credential_source",
   190  				SourceProfile: &sharedConfig{
   191  					Profile:           "multiple_assume_role_with_credential_source",
   192  					RoleARN:           "multiple_assume_role_with_credential_source_role_arn",
   193  					SourceProfileName: "assume_role_with_credential_source",
   194  					SourceProfile: &sharedConfig{
   195  						Profile:          "assume_role_with_credential_source",
   196  						RoleARN:          "assume_role_with_credential_source_role_arn",
   197  						CredentialSource: credSourceEc2Metadata,
   198  					},
   199  				},
   200  			},
   201  		},
   202  		{
   203  			Filenames: []string{testConfigFilename},
   204  			Profile:   "with_sts_regional",
   205  			Expected: sharedConfig{
   206  				Profile:             "with_sts_regional",
   207  				STSRegionalEndpoint: endpoints.RegionalSTSEndpoint,
   208  			},
   209  		},
   210  		{
   211  			Filenames: []string{testConfigFilename},
   212  			Profile:   "with_s3_us_east_1_regional",
   213  			Expected: sharedConfig{
   214  				Profile:                   "with_s3_us_east_1_regional",
   215  				S3UsEast1RegionalEndpoint: endpoints.RegionalS3UsEast1Endpoint,
   216  			},
   217  		},
   218  		{
   219  			Filenames: []string{testConfigFilename},
   220  			Profile:   "sso_creds",
   221  			Expected: sharedConfig{
   222  				Profile:      "sso_creds",
   223  				SSOAccountID: "012345678901",
   224  				SSORegion:    "us-west-2",
   225  				SSORoleName:  "TestRole",
   226  				SSOStartURL:  "https://127.0.0.1/start",
   227  			},
   228  		},
   229  		{
   230  			Filenames: []string{testConfigFilename},
   231  			Profile:   "source_sso_creds",
   232  			Expected: sharedConfig{
   233  				Profile:           "source_sso_creds",
   234  				RoleARN:           "source_sso_creds_arn",
   235  				SourceProfileName: "sso_creds",
   236  				SourceProfile: &sharedConfig{
   237  					Profile:      "sso_creds",
   238  					SSOAccountID: "012345678901",
   239  					SSORegion:    "us-west-2",
   240  					SSORoleName:  "TestRole",
   241  					SSOStartURL:  "https://127.0.0.1/start",
   242  				},
   243  			},
   244  		},
   245  		{
   246  			Filenames: []string{testConfigFilename},
   247  			Profile:   "sso_and_static",
   248  			Expected: sharedConfig{
   249  				Profile: "sso_and_static",
   250  				Creds: credentials.Value{
   251  					AccessKeyID:     "sso_and_static_akid",
   252  					SecretAccessKey: "sso_and_static_secret",
   253  					SessionToken:    "sso_and_static_token",
   254  					ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
   255  				},
   256  				SSOAccountID: "012345678901",
   257  				SSORegion:    "us-west-2",
   258  				SSORoleName:  "TestRole",
   259  				SSOStartURL:  "https://THIS_SHOULD_NOT_BE_IN_TESTDATA_CACHE/start",
   260  			},
   261  		},
   262  		{
   263  			Filenames: []string{testConfigFilename},
   264  			Profile:   "source_sso_and_assume",
   265  			Expected: sharedConfig{
   266  				Profile:           "source_sso_and_assume",
   267  				RoleARN:           "source_sso_and_assume_arn",
   268  				SourceProfileName: "sso_and_assume",
   269  				SourceProfile: &sharedConfig{
   270  					Profile:           "sso_and_assume",
   271  					RoleARN:           "sso_with_assume_role_arn",
   272  					SourceProfileName: "multiple_assume_role_with_credential_source",
   273  					SourceProfile: &sharedConfig{
   274  						Profile:           "multiple_assume_role_with_credential_source",
   275  						RoleARN:           "multiple_assume_role_with_credential_source_role_arn",
   276  						SourceProfileName: "assume_role_with_credential_source",
   277  						SourceProfile: &sharedConfig{
   278  							Profile:          "assume_role_with_credential_source",
   279  							RoleARN:          "assume_role_with_credential_source_role_arn",
   280  							CredentialSource: credSourceEc2Metadata,
   281  						},
   282  					},
   283  				},
   284  			},
   285  		},
   286  		{
   287  			Filenames: []string{testConfigFilename},
   288  			Profile:   "sso_mixed_credproc",
   289  			Expected: sharedConfig{
   290  				Profile:           "sso_mixed_credproc",
   291  				SSOAccountID:      "012345678901",
   292  				SSORegion:         "us-west-2",
   293  				SSORoleName:       "TestRole",
   294  				SSOStartURL:       "https://127.0.0.1/start",
   295  				CredentialProcess: "/path/to/process",
   296  			},
   297  		},
   298  		{
   299  			Filenames: []string{testConfigFilename},
   300  			Profile:   "EC2MetadataServiceEndpoint",
   301  			Expected: sharedConfig{
   302  				Profile:         "EC2MetadataServiceEndpoint",
   303  				EC2IMDSEndpoint: "http://endpoint.localhost",
   304  			},
   305  		},
   306  		{
   307  			Filenames: []string{testConfigFilename},
   308  			Profile:   "EC2MetadataServiceEndpointModeIPv6",
   309  			Expected: sharedConfig{
   310  				Profile:             "EC2MetadataServiceEndpointModeIPv6",
   311  				EC2IMDSEndpointMode: endpoints.EC2IMDSEndpointModeStateIPv6,
   312  			},
   313  		},
   314  		{
   315  			Filenames: []string{testConfigFilename},
   316  			Profile:   "EC2MetadataServiceEndpointModeIPv4",
   317  			Expected: sharedConfig{
   318  				Profile:             "EC2MetadataServiceEndpointModeIPv4",
   319  				EC2IMDSEndpointMode: endpoints.EC2IMDSEndpointModeStateIPv4,
   320  			},
   321  		},
   322  		{
   323  			Filenames: []string{testConfigFilename},
   324  			Profile:   "EC2MetadataServiceEndpointModeUnknown",
   325  			Expected: sharedConfig{
   326  				Profile: "EC2MetadataServiceEndpointModeUnknown",
   327  			},
   328  			Err: fmt.Errorf("failed to load ec2_metadata_service_endpoint_mode from shared config"),
   329  		},
   330  		{
   331  			Filenames: []string{testConfigFilename},
   332  			Profile:   "EC2MetadataServiceEndpointAndModeMixed",
   333  			Expected: sharedConfig{
   334  				Profile:             "EC2MetadataServiceEndpointAndModeMixed",
   335  				EC2IMDSEndpoint:     "http://endpoint.localhost",
   336  				EC2IMDSEndpointMode: endpoints.EC2IMDSEndpointModeStateIPv6,
   337  			},
   338  		},
   339  	}
   340  
   341  	for i, c := range cases {
   342  		t.Run(strconv.Itoa(i)+"_"+c.Profile, func(t *testing.T) {
   343  			cfg, err := loadSharedConfig(c.Profile, c.Filenames, true)
   344  			if c.Err != nil {
   345  				if err == nil {
   346  					t.Fatalf("expect error, got none")
   347  				}
   348  				if e, a := c.Err.Error(), err.Error(); !strings.Contains(a, e) {
   349  					t.Errorf("expect %v, to be in %v", e, a)
   350  				}
   351  				return
   352  			}
   353  
   354  			if err != nil {
   355  				t.Fatalf("expect no error, got %v", err)
   356  			}
   357  			if e, a := c.Expected, cfg; !reflect.DeepEqual(e, a) {
   358  				t.Errorf("expect %v, got %v", e, a)
   359  			}
   360  		})
   361  	}
   362  }
   363  
   364  func TestLoadSharedConfigFromFile(t *testing.T) {
   365  	filename := testConfigFilename
   366  	f, err := ini.OpenFile(filename)
   367  	if err != nil {
   368  		t.Fatalf("failed to load test config file, %s, %v", filename, err)
   369  	}
   370  	iniFile := sharedConfigFile{IniData: f, Filename: filename}
   371  
   372  	cases := []struct {
   373  		Profile  string
   374  		Expected sharedConfig
   375  		Err      error
   376  	}{
   377  		{
   378  			Profile:  "default",
   379  			Expected: sharedConfig{Region: "default_region"},
   380  		},
   381  		{
   382  			Profile:  "alt_profile_name",
   383  			Expected: sharedConfig{Region: "alt_profile_name_region"},
   384  		},
   385  		{
   386  			Profile:  "short_profile_name_first",
   387  			Expected: sharedConfig{Region: "short_profile_name_first_short"},
   388  		},
   389  		{
   390  			Profile:  "partial_creds",
   391  			Expected: sharedConfig{},
   392  		},
   393  		{
   394  			Profile: "complete_creds",
   395  			Expected: sharedConfig{
   396  				Creds: credentials.Value{
   397  					AccessKeyID:     "complete_creds_akid",
   398  					SecretAccessKey: "complete_creds_secret",
   399  					ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
   400  				},
   401  			},
   402  		},
   403  		{
   404  			Profile: "complete_creds_with_token",
   405  			Expected: sharedConfig{
   406  				Creds: credentials.Value{
   407  					AccessKeyID:     "complete_creds_with_token_akid",
   408  					SecretAccessKey: "complete_creds_with_token_secret",
   409  					SessionToken:    "complete_creds_with_token_token",
   410  					ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
   411  				},
   412  			},
   413  		},
   414  		{
   415  			Profile: "full_profile",
   416  			Expected: sharedConfig{
   417  				Creds: credentials.Value{
   418  					AccessKeyID:     "full_profile_akid",
   419  					SecretAccessKey: "full_profile_secret",
   420  					ProviderName:    fmt.Sprintf("SharedConfigCredentials: %s", testConfigFilename),
   421  				},
   422  				Region: "full_profile_region",
   423  			},
   424  		},
   425  		{
   426  			Profile: "partial_assume_role",
   427  			Expected: sharedConfig{
   428  				RoleARN: "partial_assume_role_role_arn",
   429  			},
   430  		},
   431  		{
   432  			Profile: "assume_role",
   433  			Expected: sharedConfig{
   434  				RoleARN:           "assume_role_role_arn",
   435  				SourceProfileName: "complete_creds",
   436  			},
   437  		},
   438  		{
   439  			Profile: "assume_role_w_mfa",
   440  			Expected: sharedConfig{
   441  				RoleARN:           "assume_role_role_arn",
   442  				SourceProfileName: "complete_creds",
   443  				MFASerial:         "0123456789",
   444  			},
   445  		},
   446  		{
   447  			Profile: "does_not_exists",
   448  			Err:     SharedConfigProfileNotExistsError{Profile: "does_not_exists"},
   449  		},
   450  		{
   451  			Profile: "valid_arn_region",
   452  			Expected: sharedConfig{
   453  				S3UseARNRegion: true,
   454  			},
   455  		},
   456  	}
   457  
   458  	for i, c := range cases {
   459  		t.Run(strconv.Itoa(i)+"_"+c.Profile, func(t *testing.T) {
   460  			cfg := sharedConfig{}
   461  
   462  			err := cfg.setFromIniFile(c.Profile, iniFile, true)
   463  			if c.Err != nil {
   464  				if err == nil {
   465  					t.Fatalf("expect error, got none")
   466  				}
   467  				if e, a := c.Err.Error(), err.Error(); !strings.Contains(a, e) {
   468  					t.Errorf("expect %v, to be in %v", e, a)
   469  				}
   470  				return
   471  			}
   472  
   473  			if err != nil {
   474  				t.Errorf("expect no error, got %v", err)
   475  			}
   476  			if e, a := c.Expected, cfg; !reflect.DeepEqual(e, a) {
   477  				t.Errorf("expect %v, got %v", e, a)
   478  			}
   479  		})
   480  	}
   481  }
   482  
   483  func TestLoadSharedConfigIniFiles(t *testing.T) {
   484  	cases := []struct {
   485  		Filenames []string
   486  		Expected  []sharedConfigFile
   487  	}{
   488  		{
   489  			Filenames: []string{"not_exists", testConfigFilename},
   490  			Expected: []sharedConfigFile{
   491  				{Filename: testConfigFilename},
   492  			},
   493  		},
   494  		{
   495  			Filenames: []string{testConfigFilename, testConfigOtherFilename},
   496  			Expected: []sharedConfigFile{
   497  				{Filename: testConfigFilename},
   498  				{Filename: testConfigOtherFilename},
   499  			},
   500  		},
   501  	}
   502  
   503  	for i, c := range cases {
   504  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   505  			files, err := loadSharedConfigIniFiles(c.Filenames)
   506  			if err != nil {
   507  				t.Fatalf("expect no error, got %v", err)
   508  			}
   509  			if e, a := len(c.Expected), len(files); e != a {
   510  				t.Errorf("expect %v, got %v", e, a)
   511  			}
   512  
   513  			for i, expectedFile := range c.Expected {
   514  				if e, a := expectedFile.Filename, files[i].Filename; e != a {
   515  					t.Errorf("expect %v, got %v", e, a)
   516  				}
   517  			}
   518  		})
   519  	}
   520  }