diff --git a/plugins/rest/auth.go b/plugins/rest/auth.go index 567900e8b4..f69496f08b 100644 --- a/plugins/rest/auth.go +++ b/plugins/rest/auth.go @@ -721,7 +721,43 @@ func (acs *awsCredentialServiceChain) addService(service awsCredentialService) { acs.awsCredentialServices = append(acs.awsCredentialServices, service) } +type awsCredentialCheckErrors []*awsCredentialCheckError + +func (e awsCredentialCheckErrors) Error() string { + + if len(e) == 0 { + return "no error(s)" + } + + if len(e) == 1 { + return fmt.Sprintf("1 error occurred: %v", e[0].Error()) + } + + s := make([]string, len(e)) + for i, err := range e { + s[i] = err.Error() + } + + return fmt.Sprintf("%d errors occurred:\n%s", len(e), strings.Join(s, "\n")) +} + +type awsCredentialCheckError struct { + message string +} + +func newAWSCredentialError(message string) *awsCredentialCheckError { + return &awsCredentialCheckError{ + message: message, + } +} + +func (e *awsCredentialCheckError) Error() string { + return e.message +} + func (acs *awsCredentialServiceChain) credentials(ctx context.Context) (aws.Credentials, error) { + var errs awsCredentialCheckErrors + for _, service := range acs.awsCredentialServices { credential, err := service.credentials(ctx) if err != nil { @@ -731,6 +767,7 @@ func (acs *awsCredentialServiceChain) credentials(ctx context.Context) (aws.Cred return aws.Credentials{}, err } + errs = append(errs, newAWSCredentialError(err.Error())) continue } @@ -738,7 +775,7 @@ func (acs *awsCredentialServiceChain) credentials(ctx context.Context) (aws.Cred return credential, nil } - return aws.Credentials{}, errors.New("all AWS credential providers failed") + return aws.Credentials{}, fmt.Errorf("all AWS credential providers failed: %v", errs) } func (ap *awsSigningAuthPlugin) awsCredentialService() awsCredentialService { diff --git a/plugins/rest/rest_test.go b/plugins/rest/rest_test.go index a6c5f96a8b..26210cfe1a 100644 --- a/plugins/rest/rest_test.go +++ b/plugins/rest/rest_test.go @@ -1789,6 +1789,7 @@ func TestAWSCredentialServiceChain(t *testing.T) { input string wantErr bool env map[string]string + errMsg string }{ { name: "Fallback to Environment Credential", @@ -1826,6 +1827,7 @@ func TestAWSCredentialServiceChain(t *testing.T) { } }`, wantErr: true, + errMsg: "all AWS credential providers failed: 4 errors occurred", env: map[string]string{}, }, } @@ -1859,10 +1861,19 @@ func TestAWSCredentialServiceChain(t *testing.T) { awsPlugin.logger = client.logger err = awsPlugin.Prepare(req) - if err != nil && !tc.wantErr { - t.Fatalf("Unexpected error: %v", err) - } else if err == nil && tc.wantErr { - t.Fatalf("Expected error for input %v", tc.input) + + if tc.wantErr { + if err == nil { + t.Fatalf("Expected error for input %v", tc.input) + } + + if !strings.Contains(err.Error(), tc.errMsg) { + t.Fatalf("Expected error message %v but got %v", tc.errMsg, err.Error()) + } + } else { + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } } }) }