diff --git a/.gitignore b/.gitignore index c4ee5d1..9b020f5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ plan.tfplan *.log *.out *.html + +# IntelliJ IDEA project files +.idea +*.iprg diff --git a/go.mod b/go.mod index 07cf0d4..b2066c4 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( github.com/mitchellh/mapstructure v1.5.0 github.com/stretchr/testify v1.8.4 google.golang.org/grpc v1.61.0 - google.golang.org/protobuf v1.33.0 + google.golang.org/protobuf v1.35.1 ) require ( @@ -55,10 +55,10 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/zclconf/go-cty v1.10.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240125205218-1f4bbc51befe // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect diff --git a/go.sum b/go.sum index df46f5c..ad16605 100644 --- a/go.sum +++ b/go.sum @@ -210,8 +210,8 @@ go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= @@ -224,8 +224,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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -239,14 +239,14 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -269,8 +269,8 @@ google.golang.org/grpc v1.61.0 h1:TOvOcuXn30kRao+gfcvsebNEa5iZIiLkisYEkf7R7o0= google.golang.org/grpc v1.61.0/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= diff --git a/internal/credential/state.go b/internal/credential/state.go index 83c3ca8..15555f5 100644 --- a/internal/credential/state.go +++ b/internal/credential/state.go @@ -114,7 +114,7 @@ func (s *AwsCredentialPersistedState) ValidateCreds(ctx context.Context) error { return errors.BadRequestStatus("missing credentials config") } if _, err := s.CredentialsConfig.GetCallerIdentity(ctx, s.testOpts...); err != nil { - st, _ := errors.ParseAWSError(err, "validating credentials") + st, _ := errors.ParseAWSError("validating credentials", err) return st.Err() } return nil @@ -135,7 +135,7 @@ func (s *AwsCredentialPersistedState) RotateCreds(ctx context.Context) error { if err := s.CredentialsConfig.RotateKeys(ctx, append([]awsutil.Option{ awsutil.WithValidityCheckTimeout(rotationWaitTimeout), }, s.testOpts...)...); err != nil { - st, _ := errors.ParseAWSError(err, "error rotating credentials") + st, _ := errors.ParseAWSError("rotating credentials", err) return st.Err() } s.CredsLastRotatedTime = time.Now() @@ -192,7 +192,7 @@ func (s *AwsCredentialPersistedState) DeleteCreds(ctx context.Context) error { } // Otherwise treat it as an actual error. - st, _ := errors.ParseAWSError(err, "failed to delete access key") + st, _ := errors.ParseAWSError("deleting credentials", err) return st.Err() } @@ -252,17 +252,17 @@ func AwsCredentialPersistedStateFromProto(secrets *structpb.Struct, attrs *Crede accessKeyId, err := values.GetStringValue(secrets, ConstAccessKeyId, false) if err != nil { - return nil, fmt.Errorf("persisted state integrity error: %w", err) + return nil, fmt.Errorf("persisted state integrity: %w", err) } secretAccessKey, err := values.GetStringValue(secrets, ConstSecretAccessKey, false) if err != nil { - return nil, fmt.Errorf("persisted state integrity error: %w", err) + return nil, fmt.Errorf("persisted state integrity: %w", err) } credsLastRotatedTime, err := values.GetTimeValue(secrets, ConstCredsLastRotatedTime) if err != nil { - return nil, fmt.Errorf("persisted state integrity error: %w", err) + return nil, fmt.Errorf("persisted state integrity: %w", err) } s, err := NewAwsCredentialPersistedState(opts...) diff --git a/internal/credential/state_test.go b/internal/credential/state_test.go index c74234e..2bc8b7d 100644 --- a/internal/credential/state_test.go +++ b/internal/credential/state_test.go @@ -186,7 +186,7 @@ func TestAwsCredentialPersistedStateFromProto(t *testing.T) { attrs: &CredentialAttributes{ Region: "us-west-2", }, - expectedErr: "persisted state integrity error: could not parse time in value \"creds_last_rotated_time\": parsing time \"notatime\" as \"2006-01-02T15:04:05.999999999Z07:00\": cannot parse \"notatime\" as \"2006\"", + expectedErr: "persisted state integrity: could not parse time in value \"creds_last_rotated_time\": parsing time \"notatime\" as \"2006-01-02T15:04:05.999999999Z07:00\": cannot parse \"notatime\" as \"2006\"", }, { name: "option error", @@ -458,7 +458,7 @@ func TestAwsCatalogPersistedState_RotateCreds(t *testing.T) { ), }, }, - expectedErr: "aws service unknown: unknown error: error rotating credentials", + expectedErr: "aws service unknown: unknown error: rotating credentials", expectedStatusCode: codes.Unknown, }, { @@ -568,7 +568,7 @@ func TestAwsCatalogPersistedState_ReplaceCreds(t *testing.T) { }, }, credentialConfig: &awsutil.CredentialsConfig{}, - expectedErr: "aws service unknown: unknown error: failed to delete access key", + expectedErr: "aws service unknown: unknown error: deleting credentials", expectedStatusCode: codes.Unknown, }, { @@ -693,7 +693,7 @@ func TestAwsCatalogPersistedState_DeleteCreds(t *testing.T) { ), }, }, - expectedErr: "aws service unknown: unknown error: failed to delete access key", + expectedErr: "aws service unknown: unknown error: deleting credentials", expectedStatusCode: codes.Unknown, }, { diff --git a/internal/errors/error.go b/internal/errors/error.go index 5487601..5a23182 100644 --- a/internal/errors/error.go +++ b/internal/errors/error.go @@ -81,11 +81,12 @@ func InvalidArgumentError(msg string, f map[string]string) error { // and credentials. This method will fallback to parsing the http status code // when it cannot match an aws error code. This method does not handle specific // service type errors such as S3 or EC2. -func ParseAWSError(err error, msg string) (st *status.Status, permission *pb.Permission) { +func ParseAWSError(op string, err error) (st *status.Status, permission *pb.Permission) { if err == nil { return nil, nil } + msg := fmt.Sprintf("%s: %v", op, err) // find the service name of the aws api serviceName := "unknown" var oe *smithy.OperationError @@ -113,7 +114,7 @@ func ParseAWSError(err error, msg string) (st *status.Status, permission *pb.Per Codes: retry.DefaultThrottleErrorCodes, } if throttleErr.IsErrorThrottle(err).Bool() { - statusMsg := fmt.Sprintf("aws service %s: throttling error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: throttling: %s", serviceName, msg) return status.New(codes.Unavailable, statusMsg), nil } @@ -126,31 +127,31 @@ func ParseAWSError(err error, msg string) (st *status.Status, permission *pb.Per case awsErrorInvalidAccessKeyId: fallthrough case awsErrorExpiredToken: - statusMsg := fmt.Sprintf("aws service %s: invalid credentials error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: invalid credentials: %s", serviceName, msg) return status.New(codes.PermissionDenied, statusMsg), &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: apiErr.ErrorMessage(), CheckedAt: timestamppb.Now(), } case awsErrorNoSuchBucket: - statusMsg := fmt.Sprintf("aws %s error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: %s", serviceName, msg) return status.New(codes.NotFound, statusMsg), &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: apiErr.ErrorMessage(), CheckedAt: timestamppb.Now(), } case awsErrorBadDigest: - statusMsg := fmt.Sprintf("aws %s error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: %s", serviceName, msg) return status.New(codes.Aborted, statusMsg), nil case awsErrorNoSuchKey: fallthrough case awsErrorInvalidObjectState: - statusMsg := fmt.Sprintf("aws %s error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: %s", serviceName, msg) return status.New(codes.NotFound, statusMsg), nil case awsErrorRequestTimeout: fallthrough case awsErrorRequestTimeoutException: - statusMsg := fmt.Sprintf("aws %s error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: %s", serviceName, msg) return status.New(codes.DeadlineExceeded, statusMsg), nil } } @@ -165,39 +166,39 @@ func ParseAWSError(err error, msg string) (st *status.Status, permission *pb.Per defer httpErr.Response.Body.Close() switch httpErr.HTTPStatusCode() { case http.StatusBadRequest: - statusMsg := fmt.Sprintf("aws service %s: bad request error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: bad request: %s", serviceName, msg) return status.New(codes.InvalidArgument, statusMsg), nil case http.StatusUnauthorized: - statusMsg := fmt.Sprintf("aws service %s: invalid credentials error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: invalid credentials: %s", serviceName, msg) return status.New(codes.PermissionDenied, statusMsg), &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: buf.String(), CheckedAt: timestamppb.Now(), } case http.StatusForbidden: - statusMsg := fmt.Sprintf("aws service %s: invalid credentials error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: invalid credentials: %s", serviceName, msg) return status.New(codes.PermissionDenied, statusMsg), &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: buf.String(), CheckedAt: timestamppb.Now(), } case http.StatusNotFound: - statusMsg := fmt.Sprintf("aws service %s: resource not found error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: resource not found: %s", serviceName, msg) return status.New(codes.NotFound, statusMsg), nil case http.StatusTooManyRequests: - statusMsg := fmt.Sprintf("aws service %s: throttling error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: throttling: %s", serviceName, msg) return status.New(codes.Unavailable, statusMsg), nil case http.StatusInternalServerError: fallthrough case http.StatusBadGateway: fallthrough case http.StatusServiceUnavailable: - statusMsg := fmt.Sprintf("aws service %s: connectivity error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: connectivity: %s", serviceName, msg) return status.New(codes.Unavailable, statusMsg), nil case http.StatusRequestTimeout: fallthrough case http.StatusGatewayTimeout: - statusMsg := fmt.Sprintf("aws service %s: timeout error: %s", serviceName, msg) + statusMsg := fmt.Sprintf("aws service %s: timeout: %s", serviceName, msg) return status.New(codes.DeadlineExceeded, statusMsg), nil } } diff --git a/internal/errors/error_test.go b/internal/errors/error_test.go index 67d3a8d..ec4bb06 100644 --- a/internal/errors/error_test.go +++ b/internal/errors/error_test.go @@ -44,7 +44,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-bad-request", err: TestAwsHttpResponseError(http.StatusBadRequest, "bad request"), expectedStatusCode: codes.InvalidArgument, - expectedStatusMsg: "aws service unknown: bad request error: test", + expectedStatusMsg: "aws service unknown: bad request: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -53,7 +53,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-unauthorized", err: TestAwsHttpResponseError(http.StatusUnauthorized, "unauthorized request"), expectedStatusCode: codes.PermissionDenied, - expectedStatusMsg: "aws service unknown: invalid credentials error: test", + expectedStatusMsg: "aws service unknown: invalid credentials: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: "unauthorized request", @@ -64,7 +64,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-forbidden", err: TestAwsHttpResponseError(http.StatusForbidden, "forbidden request"), expectedStatusCode: codes.PermissionDenied, - expectedStatusMsg: "aws service unknown: invalid credentials error: test", + expectedStatusMsg: "aws service unknown: invalid credentials: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: "forbidden request", @@ -75,7 +75,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-not-found", err: TestAwsHttpResponseError(http.StatusNotFound, "not found request"), expectedStatusCode: codes.NotFound, - expectedStatusMsg: "aws service unknown: resource not found error: test", + expectedStatusMsg: "aws service unknown: resource not found: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -84,7 +84,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-too-many-requests", err: TestAwsHttpResponseError(http.StatusTooManyRequests, "too many requests"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -93,7 +93,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-request-timeout", err: TestAwsHttpResponseError(http.StatusRequestTimeout, "request timeout"), expectedStatusCode: codes.DeadlineExceeded, - expectedStatusMsg: "aws service unknown: timeout error: test", + expectedStatusMsg: "aws service unknown: timeout: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -102,7 +102,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-internal-server-error", err: TestAwsHttpResponseError(http.StatusInternalServerError, "internal server error"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: connectivity error: test", + expectedStatusMsg: "aws service unknown: connectivity: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -111,7 +111,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-bad-gateway", err: TestAwsHttpResponseError(http.StatusBadGateway, "bad gateway"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: connectivity error: test", + expectedStatusMsg: "aws service unknown: connectivity: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -120,7 +120,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-service-unavailable", err: TestAwsHttpResponseError(http.StatusServiceUnavailable, "service unavailable"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: connectivity error: test", + expectedStatusMsg: "aws service unknown: connectivity: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -129,7 +129,7 @@ func Test_ParseAWSError(t *testing.T) { name: "http-status-code-gateway-timeout", err: TestAwsHttpResponseError(http.StatusGatewayTimeout, "gateway timeout"), expectedStatusCode: codes.DeadlineExceeded, - expectedStatusMsg: "aws service unknown: timeout error: test", + expectedStatusMsg: "aws service unknown: timeout: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -138,7 +138,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-throttling", err: TestAwsError("Throttling", "throttling error"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -147,7 +147,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-throttling-exception", err: TestAwsError("ThrottlingException", "throttling exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -156,7 +156,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-throttled-exception", err: TestAwsError("ThrottledException", "throttled exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -165,7 +165,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-throttled-exception", err: TestAwsError("RequestThrottledException", "request throttled exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -174,7 +174,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-too-many-requests-exception", err: TestAwsError("TooManyRequestsException", "too many requests exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -183,7 +183,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-provisioned-throughput-exceeded-exception", err: TestAwsError("ProvisionedThroughputExceededException", "provisioned throughput exceeded exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -192,7 +192,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-transaction-in-progress-exception", err: TestAwsError("TransactionInProgressException", "transaction in progress exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -201,7 +201,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-limit-exceeded", err: TestAwsError("RequestLimitExceeded", "request limit exceeded"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -210,7 +210,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-bandwidth-limit-exceeded", err: TestAwsError("BandwidthLimitExceeded", "bandwidth limit exceeded"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -219,7 +219,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-limit-exceeded-exception", err: TestAwsError("LimitExceededException", "limit exceeded exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -228,7 +228,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-throttled", err: TestAwsError("RequestThrottled", "request throttled"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -237,7 +237,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-slow-down", err: TestAwsError("SlowDown", "slow down"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -246,7 +246,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-prior-request-not-complete", err: TestAwsError("PriorRequestNotComplete", "prior request not complete"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -255,7 +255,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-ec2-throttled-exception", err: TestAwsError("EC2ThrottledException", "ec2 throttled exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service unknown: throttling error: test", + expectedStatusMsg: "aws service unknown: throttling: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -264,7 +264,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-timeout", err: TestAwsError("RequestTimeout", "request timeout"), expectedStatusCode: codes.DeadlineExceeded, - expectedStatusMsg: "aws unknown error: test", + expectedStatusMsg: "aws service unknown: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -273,7 +273,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-timeout-exception", err: TestAwsError("RequestTimeoutException", "request timeout exception"), expectedStatusCode: codes.DeadlineExceeded, - expectedStatusMsg: "aws unknown error: test", + expectedStatusMsg: "aws service unknown: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_UNKNOWN, }, @@ -282,7 +282,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-access-denied", err: TestAwsError(awsErrorAccessDenied, "not authorized to perform action"), expectedStatusCode: codes.PermissionDenied, - expectedStatusMsg: "aws service unknown: invalid credentials error: test", + expectedStatusMsg: "aws service unknown: invalid credentials: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: "not authorized to perform action", @@ -293,7 +293,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-invalid-access-key-id", err: TestAwsError(awsErrorInvalidAccessKeyId, "The AWS Access Key Id you provided does not exist in our records."), expectedStatusCode: codes.PermissionDenied, - expectedStatusMsg: "aws service unknown: invalid credentials error: test", + expectedStatusMsg: "aws service unknown: invalid credentials: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: "The AWS Access Key Id you provided does not exist in our records.", @@ -304,7 +304,7 @@ func Test_ParseAWSError(t *testing.T) { name: "aws-request-expired-token", err: TestAwsError(awsErrorExpiredToken, "The security token included in the request is expired."), expectedStatusCode: codes.PermissionDenied, - expectedStatusMsg: "aws service unknown: invalid credentials error: test", + expectedStatusMsg: "aws service unknown: invalid credentials: test", expectedPermission: &pb.Permission{ State: pb.StateType_STATE_TYPE_ERROR, ErrorDetails: "The security token included in the request is expired.", @@ -316,14 +316,14 @@ func Test_ParseAWSError(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require, assert := require.New(t), assert.New(t) - actualStatus, permission := ParseAWSError(tt.err, "test") + actualStatus, permission := ParseAWSError("test", tt.err) if tt.expectedStatusCode == codes.OK { require.Nil(actualStatus) return } require.Equal(tt.expectedStatusCode, actualStatus.Code()) - require.Equal(tt.expectedStatusMsg, actualStatus.Message()) + require.Contains(actualStatus.Message(), tt.expectedStatusMsg) require.Len(actualStatus.Details(), 0) CheckSimilarPermission(assert, tt.expectedPermission, permission, true) }) diff --git a/plugin/service/host/plugin_test.go b/plugin/service/host/plugin_test.go index 3fd0efc..0c809e2 100644 --- a/plugin/service/host/plugin_test.go +++ b/plugin/service/host/plugin_test.go @@ -683,7 +683,7 @@ func TestPluginOnCreateCatalogErr(t *testing.T) { ), }), }, - expectedErrContains: "error rotating credentials", + expectedErrContains: "rotating credentials", expectedErrCode: codes.Unknown, }, { @@ -1089,7 +1089,7 @@ func TestPluginOnUpdateCatalogErr(t *testing.T) { ), }), }, - expectedErrContains: "failed to delete access key", + expectedErrContains: "deleting credentials", expectedErrCode: codes.Unknown, }, { @@ -1167,7 +1167,7 @@ func TestPluginOnUpdateCatalogErr(t *testing.T) { ), }), }, - expectedErrContains: "error rotating credentials", + expectedErrContains: "rotating credentials", expectedErrCode: codes.Unknown, }, { @@ -1298,7 +1298,7 @@ func TestPluginOnDeleteCatalogErr(t *testing.T) { ), }), }, - expectedErrContains: "aws service unknown: unknown error: failed to delete access key", + expectedErrContains: "aws service unknown: unknown error: deleting credentials:", expectedErrCode: codes.Unknown, }, } diff --git a/plugin/service/storage/error.go b/plugin/service/storage/error.go index 950921b..2039178 100644 --- a/plugin/service/storage/error.go +++ b/plugin/service/storage/error.go @@ -50,12 +50,12 @@ func setStatePermission(req any, permission *pb.Permission) *pb.StorageBucketCre // credentials, and connectivity error types. // // https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html -func parseS3Error(err error, msg string, req any) *status.Status { +func parseS3Error(op string, err error, req any) *status.Status { if err == nil { return nil } - st, p := errors.ParseAWSError(err, msg) + st, p := errors.ParseAWSError(op, err) if p != nil { state := setStatePermission(req, p) if st, err = st.WithDetails(state); err != nil { diff --git a/plugin/service/storage/error_test.go b/plugin/service/storage/error_test.go index dca3197..3832467 100644 --- a/plugin/service/storage/error_test.go +++ b/plugin/service/storage/error_test.go @@ -34,7 +34,7 @@ func Test_ParseS3Error(t *testing.T) { req: &pb.GetObjectRequest{}, err: TestAwsS3Error("NoSuchBucket", "GetObject", "no such bucket"), expectedStatusCode: codes.NotFound, - expectedStatusMsg: "aws s3 error: test", + expectedStatusMsg: "aws service s3: test:", expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ Read: &pb.Permission{ @@ -50,7 +50,7 @@ func Test_ParseS3Error(t *testing.T) { req: &pb.GetObjectRequest{}, err: TestAwsS3Error("NoSuchKey", "GetObject", "no such key"), expectedStatusCode: codes.NotFound, - expectedStatusMsg: "aws s3 error: test", + expectedStatusMsg: "aws service s3: test:", expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ Read: &pb.Permission{ @@ -66,7 +66,7 @@ func Test_ParseS3Error(t *testing.T) { err: errors.TestAwsHttpResponseError(404, "not found"), expectedStatusCode: codes.NotFound, // cannot embed services within mock http errors, therefore unknown service - expectedStatusMsg: "aws service unknown: resource not found error: test", + expectedStatusMsg: "aws service unknown: resource not found: test:", expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ Read: &pb.Permission{ @@ -81,7 +81,7 @@ func Test_ParseS3Error(t *testing.T) { req: &pb.GetObjectRequest{}, err: TestAwsS3Error("InvalidObjectState", "GetObject", "invalid object state"), expectedStatusCode: codes.NotFound, - expectedStatusMsg: "aws s3 error: test", + expectedStatusMsg: "aws service s3: test:", expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ Read: &pb.Permission{ @@ -96,7 +96,7 @@ func Test_ParseS3Error(t *testing.T) { req: &pb.PutObjectRequest{}, err: TestAwsS3Error(s3ErrorBadDigest, "PutObject", "checksum mismatch"), expectedStatusCode: codes.Aborted, - expectedStatusMsg: "aws s3 error: test", + expectedStatusMsg: "aws service s3: test:", expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ Write: &pb.Permission{ @@ -111,7 +111,7 @@ func Test_ParseS3Error(t *testing.T) { req: &pb.GetObjectRequest{}, err: TestAwsS3Error("Throttling", "action", "throttling exception"), expectedStatusCode: codes.Unavailable, - expectedStatusMsg: "aws service s3: throttling error: test", + expectedStatusMsg: "aws service s3: throttling: test:", expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ Read: &pb.Permission{ @@ -126,7 +126,7 @@ func Test_ParseS3Error(t *testing.T) { req: &pb.GetObjectRequest{}, err: TestAwsS3Error("RequestTimeout", "action", "request timeout"), expectedStatusCode: codes.DeadlineExceeded, - expectedStatusMsg: "aws s3 error: test", + expectedStatusMsg: "aws service s3: test:", expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ Read: &pb.Permission{ @@ -141,7 +141,7 @@ func Test_ParseS3Error(t *testing.T) { req: &pb.GetObjectRequest{}, err: TestAwsS3Error("AccessDenied", "action", "access denied"), expectedStatusCode: codes.PermissionDenied, - expectedStatusMsg: "aws service s3: invalid credentials error: test", + expectedStatusMsg: "aws service s3: invalid credentials: test:", expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ Read: &pb.Permission{ @@ -157,14 +157,14 @@ func Test_ParseS3Error(t *testing.T) { t.Run(tt.name, func(t *testing.T) { require, assert := require.New(t), assert.New(t) - actualStatus := parseS3Error(tt.err, "test", tt.req) + actualStatus := parseS3Error("test", tt.err, tt.req) if tt.expectedStatusCode == codes.OK { require.Nil(actualStatus) return } require.Equal(tt.expectedStatusCode, actualStatus.Code()) - require.Equal(tt.expectedStatusMsg, actualStatus.Message()) + require.Contains(actualStatus.Message(), tt.expectedStatusMsg) require.Len(actualStatus.Details(), 1) foundDetail := false diff --git a/plugin/service/storage/plugin.go b/plugin/service/storage/plugin.go index 08b81e0..e29e05e 100644 --- a/plugin/service/storage/plugin.go +++ b/plugin/service/storage/plugin.go @@ -357,7 +357,7 @@ func (p *StoragePlugin) HeadObject(ctx context.Context, req *pb.HeadObjectReques Key: aws.String(objectKey), }) if err != nil { - return nil, parseS3Error(err, "failed to head object", req).Err() + return nil, parseS3Error("head object", err, req).Err() } return &pb.HeadObjectResponse{ ContentLength: resp.ContentLength, @@ -483,7 +483,7 @@ func (p *StoragePlugin) GetObject(req *pb.GetObjectRequest, stream pb.StoragePlu Key: aws.String(objectKey), }) if err != nil { - return parseS3Error(err, "failed to get object", req).Err() + return parseS3Error("get object", err, req).Err() } defer resp.Body.Close() @@ -608,7 +608,7 @@ func (p *StoragePlugin) PutObject(ctx context.Context, req *pb.PutObjectRequest) ChecksumSHA256: aws.String(checksum), }) if err != nil { - return nil, parseS3Error(err, "failed to put object", req).Err() + return nil, parseS3Error("put object", err, req).Err() } if resp.ChecksumSHA256 == nil { return nil, errors.UnknownStatus("missing checksum response from aws") @@ -696,7 +696,7 @@ func (p *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObjects Key: aws.String(prefix), }) if err != nil { - return nil, parseS3Error(err, "failed to delete object", req).Err() + return nil, parseS3Error("delete object", err, req).Err() } return &pb.DeleteObjectsResponse{ ObjectsDeleted: uint32(1), @@ -716,7 +716,7 @@ func (p *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObjects ContinuationToken: conToken, }) if err != nil { - return nil, parseS3Error(err, "failed to list objects", req).Err() + return nil, parseS3Error("list objects", err, req).Err() } truncated = res.IsTruncated conToken = res.NextContinuationToken @@ -738,7 +738,7 @@ func (p *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObjects }, }) if err != nil { - return nil, parseS3Error(err, "failed to delete objects", req).Err() + return nil, parseS3Error("delete objects", err, req).Err() } deleted += len(res.Deleted) } @@ -786,7 +786,7 @@ func dryRunValidation(ctx context.Context, state *awsStoragePersistedState, attr Body: bytes.NewReader([]byte("hashicorp boundary aws plugin access test")), }); err != nil { var st *status.Status - st, permissions.Write = errors.ParseAWSError(err, "failed to put object") + st, permissions.Write = errors.ParseAWSError("put object", err) errs = multierror.Append(errs, st.Err()) } else { permissions.Write = &pb.Permission{State: pb.StateType_STATE_TYPE_OK, CheckedAt: timestamppb.Now()} @@ -797,7 +797,7 @@ func dryRunValidation(ctx context.Context, state *awsStoragePersistedState, attr Key: aws.String(objectKey), }); err != nil { var st *status.Status - st, permissions.Read = errors.ParseAWSError(err, "failed to get object") + st, permissions.Read = errors.ParseAWSError("get object", err) errs = multierror.Append(errs, st.Err()) } else { permissions.Read = &pb.Permission{State: pb.StateType_STATE_TYPE_OK, CheckedAt: timestamppb.Now()} @@ -808,7 +808,7 @@ func dryRunValidation(ctx context.Context, state *awsStoragePersistedState, attr Key: aws.String(objectKey), }); err != nil { var st *status.Status - st, permissions.Read = errors.ParseAWSError(err, "failed to head object") + st, permissions.Read = errors.ParseAWSError("head object", err) errs = multierror.Append(errs, st.Err()) } @@ -817,7 +817,7 @@ func dryRunValidation(ctx context.Context, state *awsStoragePersistedState, attr Prefix: aws.String(objectKey), }); err != nil { var st *status.Status - st, permissions.Read = errors.ParseAWSError(err, "failed to list object") + st, permissions.Read = errors.ParseAWSError("list object", err) errs = multierror.Append(errs, st.Err()) } else if res == nil || len(res.Contents) != 1 || *res.Contents[0].Key != objectKey { permissions.Read = &pb.Permission{State: pb.StateType_STATE_TYPE_UNKNOWN, CheckedAt: timestamppb.Now()} @@ -829,7 +829,7 @@ func dryRunValidation(ctx context.Context, state *awsStoragePersistedState, attr Key: aws.String(objectKey), }); err != nil { var st *status.Status - st, permissions.Delete = errors.ParseAWSError(err, "failed to delete object") + st, permissions.Delete = errors.ParseAWSError("delete object", err) errs = multierror.Append(errs, st.Err()) } else { permissions.Delete = &pb.Permission{State: pb.StateType_STATE_TYPE_OK, CheckedAt: timestamppb.Now()} diff --git a/plugin/service/storage/plugin_test.go b/plugin/service/storage/plugin_test.go index 108899e..600afab 100644 --- a/plugin/service/storage/plugin_test.go +++ b/plugin/service/storage/plugin_test.go @@ -153,7 +153,7 @@ func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) { ), }), }, - expectedErrContains: "aws service unknown: unknown error: error rotating credentials", + expectedErrContains: "aws service unknown: unknown error: rotating credentials:", expectedErrCode: codes.Unknown, expectedDetails: nil, }, @@ -178,7 +178,7 @@ func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) { }), )), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to put object", + expectedErrContains: "aws service s3: invalid credentials: put object:", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -211,7 +211,7 @@ func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) { }), )), }, - expectedErrContains: "aws service s3: throttling error: failed to put object", + expectedErrContains: "aws service s3: throttling: put object:", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -245,7 +245,7 @@ func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to get object", + expectedErrContains: "aws service s3: invalid credentials: get object:", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -280,7 +280,7 @@ func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to get object", + expectedErrContains: "aws service s3: throttling: get object:", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -314,7 +314,7 @@ func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to head object", + expectedErrContains: "aws service s3: invalid credentials: head object:", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -349,7 +349,7 @@ func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to head object", + expectedErrContains: "aws service s3: throttling: head object:", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -384,7 +384,7 @@ func TestStoragePlugin_OnCreateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to delete object", + expectedErrContains: "aws service s3: invalid credentials: delete object:", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -857,7 +857,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), }), }, - expectedErrContains: "aws service unknown: unknown error: failed to delete access key", + expectedErrContains: "aws service unknown: unknown error: deleting credentials:", expectedErrCode: codes.Unknown, }, { @@ -896,7 +896,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), }), }, - expectedErrContains: "aws service unknown: unknown error: error rotating credentials", + expectedErrContains: "aws service unknown: unknown error: rotating credentials", expectedErrCode: codes.Unknown, }, { @@ -920,7 +920,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { testMockS3WithPutObjectError(TestAwsS3Error("AccessDenied", "PutObject", "not authorized")), )), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to put object", + expectedErrContains: "aws service s3: invalid credentials: put object:", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -953,7 +953,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { testMockS3WithPutObjectError(TestAwsS3Error("ThrottlingException", "PutObject", "throttling exception")), )), }, - expectedErrContains: "aws service s3: throttling error: failed to put object", + expectedErrContains: "aws service s3: throttling: put object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -987,7 +987,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to get object", + expectedErrContains: "aws service s3: invalid credentials: get object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -1022,7 +1022,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to get object", + expectedErrContains: "aws service s3: throttling: get object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -1056,7 +1056,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to head object", + expectedErrContains: "aws service s3: invalid credentials: head object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -1091,7 +1091,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to head object", + expectedErrContains: "aws service s3: throttling: head object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -1255,7 +1255,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to head object", + expectedErrContains: "aws service s3: invalid credentials: head object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -1363,7 +1363,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to put object", + expectedErrContains: "aws service s3: invalid credentials: put object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -1486,7 +1486,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), }), }, - expectedErrContains: "aws service unknown: unknown error: failed to delete access key", + expectedErrContains: "aws service unknown: unknown error: deleting credentials", expectedErrCode: codes.Unknown, }, { @@ -1599,7 +1599,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to put object", + expectedErrContains: "aws service s3: invalid credentials: put object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -1738,7 +1738,7 @@ func TestStoragePlugin_OnUpdateStorageBucket(t *testing.T) { ), }), }, - expectedErrContains: "aws service unknown: unknown error: error rotating credentials", + expectedErrContains: "aws service unknown: unknown error: rotating credentials", expectedErrCode: codes.Unknown, }, { @@ -1973,7 +1973,7 @@ func TestStoragePlugin_OnDeleteStorageBucket(t *testing.T) { ), }), }, - expectedErrContains: "aws service unknown: unknown error: failed to delete access key", + expectedErrContains: "aws service unknown: unknown error: deleting credentials", expectedErrCode: codes.Unknown, }, { @@ -2172,7 +2172,7 @@ func TestStoragePlugin_HeadObject(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to head object", + expectedErrContains: "aws service s3: invalid credentials: head object", expectedErrCode: codes.PermissionDenied, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2196,7 +2196,7 @@ func TestStoragePlugin_HeadObject(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to head object", + expectedErrContains: "aws service s3: throttling: head object", expectedErrCode: codes.Unavailable, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2219,7 +2219,7 @@ func TestStoragePlugin_HeadObject(t *testing.T) { ), ), }, - expectedErrContains: "aws s3 error: failed to head object", + expectedErrContains: "aws service s3: head object", expectedErrCode: codes.NotFound, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2425,7 +2425,7 @@ func TestStoragePlugin_ValidatePermissions(t *testing.T) { }), )), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to put object", + expectedErrContains: "aws service s3: invalid credentials: put object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2458,7 +2458,7 @@ func TestStoragePlugin_ValidatePermissions(t *testing.T) { }), )), }, - expectedErrContains: "aws service s3: throttling error: failed to put object", + expectedErrContains: "aws service s3: throttling: put object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2492,7 +2492,7 @@ func TestStoragePlugin_ValidatePermissions(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to get object", + expectedErrContains: "aws service s3: invalid credentials: get object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2527,7 +2527,7 @@ func TestStoragePlugin_ValidatePermissions(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to get object", + expectedErrContains: "aws service s3: throttling: get object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2561,7 +2561,7 @@ func TestStoragePlugin_ValidatePermissions(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to head object", + expectedErrContains: "aws service s3: invalid credentials: head object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2596,7 +2596,7 @@ func TestStoragePlugin_ValidatePermissions(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to head object", + expectedErrContains: "aws service s3: throttling: head object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2683,7 +2683,7 @@ func TestStoragePlugin_ValidatePermissions(t *testing.T) { }), )), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to put object", + expectedErrContains: "aws service s3: invalid credentials: put object", expectedErrCode: codes.FailedPrecondition, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2851,7 +2851,7 @@ func TestStoragePlugin_GetObject(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to get object", + expectedErrContains: "aws service s3: invalid credentials: get object", expectedErrCode: codes.PermissionDenied, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2875,7 +2875,7 @@ func TestStoragePlugin_GetObject(t *testing.T) { ), ), }, - expectedErrContains: "aws s3 error: failed to get object", + expectedErrContains: "aws service s3: get object", expectedErrCode: codes.NotFound, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2898,7 +2898,7 @@ func TestStoragePlugin_GetObject(t *testing.T) { ), ), }, - expectedErrContains: "aws s3 error: failed to get object", + expectedErrContains: "aws service s3: get object", expectedErrCode: codes.NotFound, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2921,7 +2921,7 @@ func TestStoragePlugin_GetObject(t *testing.T) { ), ), }, - expectedErrContains: "aws s3 error: failed to get object", + expectedErrContains: "aws service s3: get object", expectedErrCode: codes.NotFound, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -2945,7 +2945,7 @@ func TestStoragePlugin_GetObject(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to get object", + expectedErrContains: "aws service s3: throttling: get object", expectedErrCode: codes.Unavailable, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3300,7 +3300,7 @@ func TestStoragePlugin_PutObject(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to put object", + expectedErrContains: "aws service s3: invalid credentials: put object", expectedErrCode: codes.PermissionDenied, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3324,7 +3324,7 @@ func TestStoragePlugin_PutObject(t *testing.T) { ), ), }, - expectedErrContains: "aws s3 error: failed to put object", + expectedErrContains: "aws service s3: put object", expectedErrCode: codes.NotFound, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3348,7 +3348,7 @@ func TestStoragePlugin_PutObject(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to put object", + expectedErrContains: "aws service s3: throttling: put object", expectedErrCode: codes.Unavailable, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3640,7 +3640,7 @@ func TestStoragePlugin_DeleteObjects(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to delete object", + expectedErrContains: "aws service s3: invalid credentials: delete object", expectedErrCode: codes.PermissionDenied, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3664,7 +3664,7 @@ func TestStoragePlugin_DeleteObjects(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to list objects", + expectedErrContains: "aws service s3: invalid credentials: list objects", expectedErrCode: codes.PermissionDenied, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3696,7 +3696,7 @@ func TestStoragePlugin_DeleteObjects(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: invalid credentials error: failed to delete objects", + expectedErrContains: "aws service s3: invalid credentials: delete objects", expectedErrCode: codes.PermissionDenied, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3720,7 +3720,7 @@ func TestStoragePlugin_DeleteObjects(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to delete object", + expectedErrContains: "aws service s3: throttling: delete object", expectedErrCode: codes.Unavailable, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3743,7 +3743,7 @@ func TestStoragePlugin_DeleteObjects(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to list objects", + expectedErrContains: "aws service s3: throttling: list objects", expectedErrCode: codes.Unavailable, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{ @@ -3774,7 +3774,7 @@ func TestStoragePlugin_DeleteObjects(t *testing.T) { ), ), }, - expectedErrContains: "aws service s3: throttling error: failed to delete objects", + expectedErrContains: "aws service s3: throttling: delete objects", expectedErrCode: codes.Unavailable, expectedDetails: &pb.StorageBucketCredentialState{ State: &pb.Permissions{