forked from remote/oauth2
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b177c21ac9 | ||
|
|
510acbce1f | ||
|
|
ec4a9b2ff2 |
2
go.mod
2
go.mod
@@ -5,7 +5,7 @@ go 1.17
|
|||||||
require (
|
require (
|
||||||
cloud.google.com/go/compute/metadata v0.2.0
|
cloud.google.com/go/compute/metadata v0.2.0
|
||||||
github.com/google/go-cmp v0.5.8
|
github.com/google/go-cmp v0.5.8
|
||||||
golang.org/x/net v0.2.0
|
golang.org/x/net v0.3.0
|
||||||
google.golang.org/appengine v1.6.7
|
google.golang.org/appengine v1.6.7
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
10
go.sum
10
go.sum
@@ -15,8 +15,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR
|
|||||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||||
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
|
golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk=
|
||||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@@ -24,15 +24,15 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||||
|
|||||||
@@ -62,6 +62,13 @@ const (
|
|||||||
// The AWS authorization header name for the auto-generated date.
|
// The AWS authorization header name for the auto-generated date.
|
||||||
awsDateHeader = "x-amz-date"
|
awsDateHeader = "x-amz-date"
|
||||||
|
|
||||||
|
// Supported AWS configuration environment variables.
|
||||||
|
awsAccessKeyId = "AWS_ACCESS_KEY_ID"
|
||||||
|
awsDefaultRegion = "AWS_DEFAULT_REGION"
|
||||||
|
awsRegion = "AWS_REGION"
|
||||||
|
awsSecretAccessKey = "AWS_SECRET_ACCESS_KEY"
|
||||||
|
awsSessionToken = "AWS_SESSION_TOKEN"
|
||||||
|
|
||||||
awsTimeFormatLong = "20060102T150405Z"
|
awsTimeFormatLong = "20060102T150405Z"
|
||||||
awsTimeFormatShort = "20060102"
|
awsTimeFormatShort = "20060102"
|
||||||
)
|
)
|
||||||
@@ -267,6 +274,49 @@ type awsRequest struct {
|
|||||||
Headers []awsRequestHeader `json:"headers"`
|
Headers []awsRequestHeader `json:"headers"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cs awsCredentialSource) validateMetadataServers() error {
|
||||||
|
if err := cs.validateMetadataServer(cs.RegionURL, "region_url"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := cs.validateMetadataServer(cs.CredVerificationURL, "url"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return cs.validateMetadataServer(cs.IMDSv2SessionTokenURL, "imdsv2_session_token_url")
|
||||||
|
}
|
||||||
|
|
||||||
|
var validHostnames []string = []string{"169.254.169.254", "fd00:ec2::254"}
|
||||||
|
|
||||||
|
func (cs awsCredentialSource) isValidMetadataServer(metadataUrl string) bool {
|
||||||
|
if metadataUrl == "" {
|
||||||
|
// Zero value means use default, which is valid.
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(metadataUrl)
|
||||||
|
if err != nil {
|
||||||
|
// Unparseable URL means invalid
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, validHostname := range validHostnames {
|
||||||
|
if u.Hostname() == validHostname {
|
||||||
|
// If it's one of the valid hostnames, everything is good
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// hostname not found in our allowlist, so not valid
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs awsCredentialSource) validateMetadataServer(metadataUrl, urlName string) error {
|
||||||
|
if !cs.isValidMetadataServer(metadataUrl) {
|
||||||
|
return fmt.Errorf("oauth2/google: invalid hostname %s for %s", metadataUrl, urlName)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (cs awsCredentialSource) doRequest(req *http.Request) (*http.Response, error) {
|
func (cs awsCredentialSource) doRequest(req *http.Request) (*http.Response, error) {
|
||||||
if cs.client == nil {
|
if cs.client == nil {
|
||||||
cs.client = oauth2.NewClient(cs.ctx, nil)
|
cs.client = oauth2.NewClient(cs.ctx, nil)
|
||||||
@@ -274,16 +324,33 @@ func (cs awsCredentialSource) doRequest(req *http.Request) (*http.Response, erro
|
|||||||
return cs.client.Do(req.WithContext(cs.ctx))
|
return cs.client.Do(req.WithContext(cs.ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func canRetrieveRegionFromEnvironment() bool {
|
||||||
|
// The AWS region can be provided through AWS_REGION or AWS_DEFAULT_REGION. Only one is
|
||||||
|
// required.
|
||||||
|
return getenv(awsRegion) != "" || getenv(awsDefaultRegion) != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func canRetrieveSecurityCredentialFromEnvironment() bool {
|
||||||
|
// Check if both AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY are available.
|
||||||
|
return getenv(awsAccessKeyId) != "" && getenv(awsSecretAccessKey) != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func shouldUseMetadataServer() bool {
|
||||||
|
return !canRetrieveRegionFromEnvironment() || !canRetrieveSecurityCredentialFromEnvironment()
|
||||||
|
}
|
||||||
|
|
||||||
func (cs awsCredentialSource) subjectToken() (string, error) {
|
func (cs awsCredentialSource) subjectToken() (string, error) {
|
||||||
if cs.requestSigner == nil {
|
if cs.requestSigner == nil {
|
||||||
awsSessionToken, err := cs.getAWSSessionToken()
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
headers := make(map[string]string)
|
headers := make(map[string]string)
|
||||||
if awsSessionToken != "" {
|
if shouldUseMetadataServer() {
|
||||||
headers[awsIMDSv2SessionTokenHeader] = awsSessionToken
|
awsSessionToken, err := cs.getAWSSessionToken()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if awsSessionToken != "" {
|
||||||
|
headers[awsIMDSv2SessionTokenHeader] = awsSessionToken
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
awsSecurityCredentials, err := cs.getSecurityCredentials(headers)
|
awsSecurityCredentials, err := cs.getSecurityCredentials(headers)
|
||||||
@@ -389,11 +456,11 @@ func (cs *awsCredentialSource) getAWSSessionToken() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cs *awsCredentialSource) getRegion(headers map[string]string) (string, error) {
|
func (cs *awsCredentialSource) getRegion(headers map[string]string) (string, error) {
|
||||||
if envAwsRegion := getenv("AWS_REGION"); envAwsRegion != "" {
|
if canRetrieveRegionFromEnvironment() {
|
||||||
return envAwsRegion, nil
|
if envAwsRegion := getenv(awsRegion); envAwsRegion != "" {
|
||||||
}
|
return envAwsRegion, nil
|
||||||
if envAwsRegion := getenv("AWS_DEFAULT_REGION"); envAwsRegion != "" {
|
}
|
||||||
return envAwsRegion, nil
|
return getenv("AWS_DEFAULT_REGION"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if cs.RegionURL == "" {
|
if cs.RegionURL == "" {
|
||||||
@@ -434,14 +501,12 @@ func (cs *awsCredentialSource) getRegion(headers map[string]string) (string, err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cs *awsCredentialSource) getSecurityCredentials(headers map[string]string) (result awsSecurityCredentials, err error) {
|
func (cs *awsCredentialSource) getSecurityCredentials(headers map[string]string) (result awsSecurityCredentials, err error) {
|
||||||
if accessKeyID := getenv("AWS_ACCESS_KEY_ID"); accessKeyID != "" {
|
if canRetrieveSecurityCredentialFromEnvironment() {
|
||||||
if secretAccessKey := getenv("AWS_SECRET_ACCESS_KEY"); secretAccessKey != "" {
|
return awsSecurityCredentials{
|
||||||
return awsSecurityCredentials{
|
AccessKeyID: getenv(awsAccessKeyId),
|
||||||
AccessKeyID: accessKeyID,
|
SecretAccessKey: getenv(awsSecretAccessKey),
|
||||||
SecretAccessKey: secretAccessKey,
|
SecurityToken: getenv(awsSessionToken),
|
||||||
SecurityToken: getenv("AWS_SESSION_TOKEN"),
|
}, nil
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
roleName, err := cs.getMetadataRoleName(headers)
|
roleName, err := cs.getMetadataRoleName(headers)
|
||||||
|
|||||||
@@ -474,6 +474,38 @@ func createDefaultAwsTestServer() *testAwsServer {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func createDefaultAwsTestServerWithImdsv2(t *testing.T) *testAwsServer {
|
||||||
|
validateSessionTokenHeaders := func(r *http.Request) {
|
||||||
|
if r.URL.Path == "/latest/api/token" {
|
||||||
|
headerValue := r.Header.Get(awsIMDSv2SessionTtlHeader)
|
||||||
|
if headerValue != awsIMDSv2SessionTtl {
|
||||||
|
t.Errorf("%q = \n%q\n want \n%q", awsIMDSv2SessionTtlHeader, headerValue, awsIMDSv2SessionTtl)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
headerValue := r.Header.Get(awsIMDSv2SessionTokenHeader)
|
||||||
|
if headerValue != "sessiontoken" {
|
||||||
|
t.Errorf("%q = \n%q\n want \n%q", awsIMDSv2SessionTokenHeader, headerValue, "sessiontoken")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return createAwsTestServer(
|
||||||
|
"/latest/meta-data/iam/security-credentials",
|
||||||
|
"/latest/meta-data/placement/availability-zone",
|
||||||
|
"https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
|
||||||
|
"/latest/api/token",
|
||||||
|
"gcp-aws-role",
|
||||||
|
"us-east-2b",
|
||||||
|
map[string]string{
|
||||||
|
"SecretAccessKey": secretAccessKey,
|
||||||
|
"AccessKeyId": accessKeyID,
|
||||||
|
"Token": securityToken,
|
||||||
|
},
|
||||||
|
"sessiontoken",
|
||||||
|
validateSessionTokenHeaders,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func (server *testAwsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (server *testAwsServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
switch p := r.URL.Path; p {
|
switch p := r.URL.Path; p {
|
||||||
case server.url:
|
case server.url:
|
||||||
@@ -553,16 +585,25 @@ func getExpectedSubjectToken(url, region, accessKeyID, secretAccessKey, security
|
|||||||
func TestAWSCredential_BasicRequest(t *testing.T) {
|
func TestAWSCredential_BasicRequest(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
|
||||||
getenv = setEnvironment(map[string]string{})
|
|
||||||
oldNow := now
|
oldNow := now
|
||||||
defer func() { now = oldNow }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
|
getenv = setEnvironment(map[string]string{})
|
||||||
now = setTime(defaultTime)
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -588,46 +629,27 @@ func TestAWSCredential_BasicRequest(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestAWSCredential_IMDSv2(t *testing.T) {
|
func TestAWSCredential_IMDSv2(t *testing.T) {
|
||||||
validateSessionTokenHeaders := func(r *http.Request) {
|
server := createDefaultAwsTestServerWithImdsv2(t)
|
||||||
if r.URL.Path == "/latest/api/token" {
|
|
||||||
headerValue := r.Header.Get(awsIMDSv2SessionTtlHeader)
|
|
||||||
if headerValue != awsIMDSv2SessionTtl {
|
|
||||||
t.Errorf("%q = \n%q\n want \n%q", awsIMDSv2SessionTtlHeader, headerValue, awsIMDSv2SessionTtl)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
headerValue := r.Header.Get(awsIMDSv2SessionTokenHeader)
|
|
||||||
if headerValue != "sessiontoken" {
|
|
||||||
t.Errorf("%q = \n%q\n want \n%q", awsIMDSv2SessionTokenHeader, headerValue, "sessiontoken")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server := createAwsTestServer(
|
|
||||||
"/latest/meta-data/iam/security-credentials",
|
|
||||||
"/latest/meta-data/placement/availability-zone",
|
|
||||||
"https://sts.{region}.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
|
|
||||||
"/latest/api/token",
|
|
||||||
"gcp-aws-role",
|
|
||||||
"us-east-2b",
|
|
||||||
map[string]string{
|
|
||||||
"SecretAccessKey": secretAccessKey,
|
|
||||||
"AccessKeyId": accessKeyID,
|
|
||||||
"Token": securityToken,
|
|
||||||
},
|
|
||||||
"sessiontoken",
|
|
||||||
validateSessionTokenHeaders,
|
|
||||||
)
|
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
|
||||||
getenv = setEnvironment(map[string]string{})
|
|
||||||
oldNow := now
|
oldNow := now
|
||||||
defer func() { now = oldNow }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
|
getenv = setEnvironment(map[string]string{})
|
||||||
now = setTime(defaultTime)
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -655,17 +677,26 @@ func TestAWSCredential_IMDSv2(t *testing.T) {
|
|||||||
func TestAWSCredential_BasicRequestWithoutSecurityToken(t *testing.T) {
|
func TestAWSCredential_BasicRequestWithoutSecurityToken(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
delete(server.Credentials, "Token")
|
delete(server.Credentials, "Token")
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
|
||||||
getenv = setEnvironment(map[string]string{})
|
|
||||||
oldNow := now
|
oldNow := now
|
||||||
defer func() { now = oldNow }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
|
getenv = setEnvironment(map[string]string{})
|
||||||
now = setTime(defaultTime)
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -693,20 +724,29 @@ func TestAWSCredential_BasicRequestWithoutSecurityToken(t *testing.T) {
|
|||||||
func TestAWSCredential_BasicRequestWithEnv(t *testing.T) {
|
func TestAWSCredential_BasicRequestWithEnv(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldNow := now
|
||||||
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{
|
getenv = setEnvironment(map[string]string{
|
||||||
"AWS_ACCESS_KEY_ID": "AKIDEXAMPLE",
|
"AWS_ACCESS_KEY_ID": "AKIDEXAMPLE",
|
||||||
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
||||||
"AWS_REGION": "us-west-1",
|
"AWS_REGION": "us-west-1",
|
||||||
})
|
})
|
||||||
oldNow := now
|
|
||||||
defer func() { now = oldNow }()
|
|
||||||
now = setTime(defaultTime)
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -734,20 +774,29 @@ func TestAWSCredential_BasicRequestWithEnv(t *testing.T) {
|
|||||||
func TestAWSCredential_BasicRequestWithDefaultEnv(t *testing.T) {
|
func TestAWSCredential_BasicRequestWithDefaultEnv(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldNow := now
|
||||||
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{
|
getenv = setEnvironment(map[string]string{
|
||||||
"AWS_ACCESS_KEY_ID": "AKIDEXAMPLE",
|
"AWS_ACCESS_KEY_ID": "AKIDEXAMPLE",
|
||||||
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
||||||
"AWS_DEFAULT_REGION": "us-west-1",
|
"AWS_REGION": "us-west-1",
|
||||||
})
|
})
|
||||||
oldNow := now
|
|
||||||
defer func() { now = oldNow }()
|
|
||||||
now = setTime(defaultTime)
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -774,21 +823,30 @@ func TestAWSCredential_BasicRequestWithDefaultEnv(t *testing.T) {
|
|||||||
func TestAWSCredential_BasicRequestWithTwoRegions(t *testing.T) {
|
func TestAWSCredential_BasicRequestWithTwoRegions(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldNow := now
|
||||||
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{
|
getenv = setEnvironment(map[string]string{
|
||||||
"AWS_ACCESS_KEY_ID": "AKIDEXAMPLE",
|
"AWS_ACCESS_KEY_ID": "AKIDEXAMPLE",
|
||||||
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
||||||
"AWS_REGION": "us-west-1",
|
"AWS_REGION": "us-west-1",
|
||||||
"AWS_DEFAULT_REGION": "us-east-1",
|
"AWS_DEFAULT_REGION": "us-east-1",
|
||||||
})
|
})
|
||||||
oldNow := now
|
|
||||||
defer func() { now = oldNow }()
|
|
||||||
now = setTime(defaultTime)
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -815,16 +873,25 @@ func TestAWSCredential_BasicRequestWithTwoRegions(t *testing.T) {
|
|||||||
func TestAWSCredential_RequestWithBadVersion(t *testing.T) {
|
func TestAWSCredential_RequestWithBadVersion(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
tfc.CredentialSource.EnvironmentID = "aws3"
|
tfc.CredentialSource.EnvironmentID = "aws3"
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{})
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
_, err := tfc.parse(context.Background())
|
_, err = tfc.parse(context.Background())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("parse() should have failed")
|
t.Fatalf("parse() should have failed")
|
||||||
}
|
}
|
||||||
@@ -836,14 +903,23 @@ func TestAWSCredential_RequestWithBadVersion(t *testing.T) {
|
|||||||
func TestAWSCredential_RequestWithNoRegionURL(t *testing.T) {
|
func TestAWSCredential_RequestWithNoRegionURL(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
tfc.CredentialSource.RegionURL = ""
|
tfc.CredentialSource.RegionURL = ""
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{})
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -863,14 +939,23 @@ func TestAWSCredential_RequestWithNoRegionURL(t *testing.T) {
|
|||||||
func TestAWSCredential_RequestWithBadRegionURL(t *testing.T) {
|
func TestAWSCredential_RequestWithBadRegionURL(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
server.WriteRegion = notFound
|
server.WriteRegion = notFound
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{})
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -890,6 +975,10 @@ func TestAWSCredential_RequestWithBadRegionURL(t *testing.T) {
|
|||||||
func TestAWSCredential_RequestWithMissingCredential(t *testing.T) {
|
func TestAWSCredential_RequestWithMissingCredential(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
server.WriteSecurityCredentials = func(w http.ResponseWriter, r *http.Request) {
|
server.WriteSecurityCredentials = func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte("{}"))
|
w.Write([]byte("{}"))
|
||||||
}
|
}
|
||||||
@@ -898,8 +987,13 @@ func TestAWSCredential_RequestWithMissingCredential(t *testing.T) {
|
|||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{})
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -919,6 +1013,10 @@ func TestAWSCredential_RequestWithMissingCredential(t *testing.T) {
|
|||||||
func TestAWSCredential_RequestWithIncompleteCredential(t *testing.T) {
|
func TestAWSCredential_RequestWithIncompleteCredential(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
server.WriteSecurityCredentials = func(w http.ResponseWriter, r *http.Request) {
|
server.WriteSecurityCredentials = func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Write([]byte(`{"AccessKeyId":"FOOBARBAS"}`))
|
w.Write([]byte(`{"AccessKeyId":"FOOBARBAS"}`))
|
||||||
}
|
}
|
||||||
@@ -927,8 +1025,13 @@ func TestAWSCredential_RequestWithIncompleteCredential(t *testing.T) {
|
|||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{})
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -948,14 +1051,23 @@ func TestAWSCredential_RequestWithIncompleteCredential(t *testing.T) {
|
|||||||
func TestAWSCredential_RequestWithNoCredentialURL(t *testing.T) {
|
func TestAWSCredential_RequestWithNoCredentialURL(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
tfc.CredentialSource.URL = ""
|
tfc.CredentialSource.URL = ""
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{})
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -975,14 +1087,23 @@ func TestAWSCredential_RequestWithNoCredentialURL(t *testing.T) {
|
|||||||
func TestAWSCredential_RequestWithBadCredentialURL(t *testing.T) {
|
func TestAWSCredential_RequestWithBadCredentialURL(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
server.WriteRolename = notFound
|
server.WriteRolename = notFound
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{})
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1002,14 +1123,23 @@ func TestAWSCredential_RequestWithBadCredentialURL(t *testing.T) {
|
|||||||
func TestAWSCredential_RequestWithBadFinalCredentialURL(t *testing.T) {
|
func TestAWSCredential_RequestWithBadFinalCredentialURL(t *testing.T) {
|
||||||
server := createDefaultAwsTestServer()
|
server := createDefaultAwsTestServer()
|
||||||
ts := httptest.NewServer(server)
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
server.WriteSecurityCredentials = notFound
|
server.WriteSecurityCredentials = notFound
|
||||||
|
|
||||||
tfc := testFileConfig
|
tfc := testFileConfig
|
||||||
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
oldGetenv := getenv
|
oldGetenv := getenv
|
||||||
defer func() { getenv = oldGetenv }()
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
getenv = setEnvironment(map[string]string{})
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
base, err := tfc.parse(context.Background())
|
base, err := tfc.parse(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1025,3 +1155,290 @@ func TestAWSCredential_RequestWithBadFinalCredentialURL(t *testing.T) {
|
|||||||
t.Errorf("subjectToken = %q, want %q", got, want)
|
t.Errorf("subjectToken = %q, want %q", got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAWSCredential_ShouldNotCallMetadataEndpointWhenCredsAreInEnv(t *testing.T) {
|
||||||
|
server := createDefaultAwsTestServer()
|
||||||
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
|
metadataTs := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
t.Error("Metadata server should not have been called.")
|
||||||
|
}))
|
||||||
|
|
||||||
|
tfc := testFileConfig
|
||||||
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
tfc.CredentialSource.IMDSv2SessionTokenURL = metadataTs.URL
|
||||||
|
|
||||||
|
oldGetenv := getenv
|
||||||
|
oldNow := now
|
||||||
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
|
getenv = setEnvironment(map[string]string{
|
||||||
|
"AWS_ACCESS_KEY_ID": "AKIDEXAMPLE",
|
||||||
|
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
||||||
|
"AWS_REGION": "us-west-1",
|
||||||
|
})
|
||||||
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
|
base, err := tfc.parse(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse() failed %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := base.subjectToken()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("retrieveSubjectToken() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := getExpectedSubjectToken(
|
||||||
|
"https://sts.us-west-1.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
|
||||||
|
"us-west-1",
|
||||||
|
"AKIDEXAMPLE",
|
||||||
|
"wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
|
||||||
|
if got, want := out, expected; !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("subjectToken = \n%q\n want \n%q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAWSCredential_ShouldCallMetadataEndpointWhenNoRegion(t *testing.T) {
|
||||||
|
server := createDefaultAwsTestServerWithImdsv2(t)
|
||||||
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
|
tfc := testFileConfig
|
||||||
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
|
oldGetenv := getenv
|
||||||
|
oldNow := now
|
||||||
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
|
getenv = setEnvironment(map[string]string{
|
||||||
|
"AWS_ACCESS_KEY_ID": accessKeyID,
|
||||||
|
"AWS_SECRET_ACCESS_KEY": secretAccessKey,
|
||||||
|
})
|
||||||
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
|
base, err := tfc.parse(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse() failed %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := base.subjectToken()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("retrieveSubjectToken() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := getExpectedSubjectToken(
|
||||||
|
"https://sts.us-east-2.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
|
||||||
|
"us-east-2",
|
||||||
|
accessKeyID,
|
||||||
|
secretAccessKey,
|
||||||
|
"",
|
||||||
|
)
|
||||||
|
|
||||||
|
if got, want := out, expected; !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("subjectToken = \n%q\n want \n%q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAWSCredential_ShouldCallMetadataEndpointWhenNoAccessKey(t *testing.T) {
|
||||||
|
server := createDefaultAwsTestServerWithImdsv2(t)
|
||||||
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
|
tfc := testFileConfig
|
||||||
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
|
oldGetenv := getenv
|
||||||
|
oldNow := now
|
||||||
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
|
getenv = setEnvironment(map[string]string{
|
||||||
|
"AWS_SECRET_ACCESS_KEY": "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY",
|
||||||
|
"AWS_REGION": "us-west-1",
|
||||||
|
})
|
||||||
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
|
base, err := tfc.parse(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse() failed %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := base.subjectToken()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("retrieveSubjectToken() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := getExpectedSubjectToken(
|
||||||
|
"https://sts.us-west-1.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
|
||||||
|
"us-west-1",
|
||||||
|
accessKeyID,
|
||||||
|
secretAccessKey,
|
||||||
|
securityToken,
|
||||||
|
)
|
||||||
|
|
||||||
|
if got, want := out, expected; !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("subjectToken = \n%q\n want \n%q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAWSCredential_ShouldCallMetadataEndpointWhenNoSecretAccessKey(t *testing.T) {
|
||||||
|
server := createDefaultAwsTestServerWithImdsv2(t)
|
||||||
|
ts := httptest.NewServer(server)
|
||||||
|
tsURL, err := neturl.Parse(ts.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("couldn't parse httptest servername")
|
||||||
|
}
|
||||||
|
|
||||||
|
tfc := testFileConfig
|
||||||
|
tfc.CredentialSource = server.getCredentialSource(ts.URL)
|
||||||
|
|
||||||
|
oldGetenv := getenv
|
||||||
|
oldNow := now
|
||||||
|
oldValidHostnames := validHostnames
|
||||||
|
defer func() {
|
||||||
|
getenv = oldGetenv
|
||||||
|
now = oldNow
|
||||||
|
validHostnames = oldValidHostnames
|
||||||
|
}()
|
||||||
|
getenv = setEnvironment(map[string]string{
|
||||||
|
"AWS_ACCESS_KEY_ID": "AKIDEXAMPLE",
|
||||||
|
"AWS_REGION": "us-west-1",
|
||||||
|
})
|
||||||
|
now = setTime(defaultTime)
|
||||||
|
validHostnames = []string{tsURL.Hostname()}
|
||||||
|
|
||||||
|
base, err := tfc.parse(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parse() failed %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := base.subjectToken()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("retrieveSubjectToken() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := getExpectedSubjectToken(
|
||||||
|
"https://sts.us-west-1.amazonaws.com?Action=GetCallerIdentity&Version=2011-06-15",
|
||||||
|
"us-west-1",
|
||||||
|
accessKeyID,
|
||||||
|
secretAccessKey,
|
||||||
|
securityToken,
|
||||||
|
)
|
||||||
|
|
||||||
|
if got, want := out, expected; !reflect.DeepEqual(got, want) {
|
||||||
|
t.Errorf("subjectToken = \n%q\n want \n%q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAWSCredential_Validations(t *testing.T) {
|
||||||
|
var metadataServerValidityTests = []struct {
|
||||||
|
name string
|
||||||
|
credSource CredentialSource
|
||||||
|
errText string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "No Metadata Server URLs",
|
||||||
|
credSource: CredentialSource{
|
||||||
|
EnvironmentID: "aws1",
|
||||||
|
RegionURL: "",
|
||||||
|
URL: "",
|
||||||
|
IMDSv2SessionTokenURL: "",
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "IPv4 Metadata Server URLs",
|
||||||
|
credSource: CredentialSource{
|
||||||
|
EnvironmentID: "aws1",
|
||||||
|
RegionURL: "http://169.254.169.254/latest/meta-data/placement/availability-zone",
|
||||||
|
URL: "http://169.254.169.254/latest/meta-data/iam/security-credentials",
|
||||||
|
IMDSv2SessionTokenURL: "http://169.254.169.254/latest/api/token",
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "IPv6 Metadata Server URLs",
|
||||||
|
credSource: CredentialSource{
|
||||||
|
EnvironmentID: "aws1",
|
||||||
|
RegionURL: "http://[fd00:ec2::254]/latest/meta-data/placement/availability-zone",
|
||||||
|
URL: "http://[fd00:ec2::254]/latest/meta-data/iam/security-credentials",
|
||||||
|
IMDSv2SessionTokenURL: "http://[fd00:ec2::254]/latest/api/token",
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
name: "Faulty RegionURL",
|
||||||
|
credSource: CredentialSource{
|
||||||
|
EnvironmentID: "aws1",
|
||||||
|
RegionURL: "http://abc.com/latest/meta-data/placement/availability-zone",
|
||||||
|
URL: "http://169.254.169.254/latest/meta-data/iam/security-credentials",
|
||||||
|
IMDSv2SessionTokenURL: "http://169.254.169.254/latest/api/token",
|
||||||
|
},
|
||||||
|
errText: "oauth2/google: invalid hostname http://abc.com/latest/meta-data/placement/availability-zone for region_url",
|
||||||
|
}, {
|
||||||
|
name: "Faulty CredVerificationURL",
|
||||||
|
credSource: CredentialSource{
|
||||||
|
EnvironmentID: "aws1",
|
||||||
|
RegionURL: "http://169.254.169.254/latest/meta-data/placement/availability-zone",
|
||||||
|
URL: "http://abc.com/latest/meta-data/iam/security-credentials",
|
||||||
|
IMDSv2SessionTokenURL: "http://169.254.169.254/latest/api/token",
|
||||||
|
},
|
||||||
|
errText: "oauth2/google: invalid hostname http://abc.com/latest/meta-data/iam/security-credentials for url",
|
||||||
|
}, {
|
||||||
|
name: "Faulty IMDSv2SessionTokenURL",
|
||||||
|
credSource: CredentialSource{
|
||||||
|
EnvironmentID: "aws1",
|
||||||
|
RegionURL: "http://169.254.169.254/latest/meta-data/placement/availability-zone",
|
||||||
|
URL: "http://169.254.169.254/latest/meta-data/iam/security-credentials",
|
||||||
|
IMDSv2SessionTokenURL: "http://abc.com/latest/api/token",
|
||||||
|
},
|
||||||
|
errText: "oauth2/google: invalid hostname http://abc.com/latest/api/token for imdsv2_session_token_url",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range metadataServerValidityTests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tfc := testFileConfig
|
||||||
|
tfc.CredentialSource = tt.credSource
|
||||||
|
|
||||||
|
oldGetenv := getenv
|
||||||
|
defer func() { getenv = oldGetenv }()
|
||||||
|
getenv = setEnvironment(map[string]string{})
|
||||||
|
|
||||||
|
_, err := tfc.parse(context.Background())
|
||||||
|
if err != nil {
|
||||||
|
if tt.errText == "" {
|
||||||
|
t.Errorf("Didn't expect an error, but got %v", err)
|
||||||
|
} else if tt.errText != err.Error() {
|
||||||
|
t.Errorf("Expected %v, but got %v", tt.errText, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if tt.errText != "" {
|
||||||
|
t.Errorf("Expected error %v, but got none", tt.errText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -213,6 +213,10 @@ func (c *Config) parse(ctx context.Context) (baseCredentialSource, error) {
|
|||||||
awsCredSource.IMDSv2SessionTokenURL = c.CredentialSource.IMDSv2SessionTokenURL
|
awsCredSource.IMDSv2SessionTokenURL = c.CredentialSource.IMDSv2SessionTokenURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := awsCredSource.validateMetadataServers(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return awsCredSource, nil
|
return awsCredSource, nil
|
||||||
}
|
}
|
||||||
} else if c.CredentialSource.File != "" {
|
} else if c.CredentialSource.File != "" {
|
||||||
|
|||||||
Reference in New Issue
Block a user