diff --git a/pkg/api/errors/errors.go b/pkg/api/errors/errors.go index 116f8e05b09..8fbcd822a50 100644 --- a/pkg/api/errors/errors.go +++ b/pkg/api/errors/errors.go @@ -159,6 +159,19 @@ func NewBadRequest(reason string) error { }} } +// NewMethodNotSupported returns an error indicating the requested action is not supported on this kind. +func NewMethodNotSupported(kind, action string) error { + return &StatusError{api.Status{ + Status: api.StatusFailure, + Code: http.StatusMethodNotAllowed, + Reason: api.StatusReasonMethodNotAllowed, + Details: &api.StatusDetails{ + Kind: kind, + }, + Message: fmt.Sprintf("%s is not supported on resources of kind %q", action, kind), + }} +} + // NewInternalError returns an error indicating the item is invalid and cannot be processed. func NewInternalError(err error) error { return &StatusError{api.Status{ @@ -192,6 +205,12 @@ func IsInvalid(err error) bool { return reasonForError(err) == api.StatusReasonInvalid } +// IsMethodNotSupported determines if the err is an error which indicates the provided action could not +// be performed because it is not supported by the server. +func IsMethodNotSupported(err error) bool { + return reasonForError(err) == api.StatusReasonMethodNotAllowed +} + // IsBadRequest determines if err is an error which indicates that the request is invalid. func IsBadRequest(err error) bool { return reasonForError(err) == api.StatusReasonBadRequest diff --git a/pkg/api/errors/errors_test.go b/pkg/api/errors/errors_test.go index d3f765c1da4..d452b7cc7aa 100644 --- a/pkg/api/errors/errors_test.go +++ b/pkg/api/errors/errors_test.go @@ -40,6 +40,12 @@ func TestErrorNew(t *testing.T) { if IsInvalid(err) { t.Errorf("expected to not be %s", api.StatusReasonInvalid) } + if IsBadRequest(err) { + t.Errorf("expected to not be %s", api.StatusReasonBadRequest) + } + if IsMethodNotSupported(err) { + t.Errorf("expected to not be %s", api.StatusReasonMethodNotAllowed) + } if !IsConflict(NewConflict("test", "2", errors.New("message"))) { t.Errorf("expected to be conflict") @@ -50,6 +56,12 @@ func TestErrorNew(t *testing.T) { if !IsInvalid(NewInvalid("test", "2", nil)) { t.Errorf("expected to be %s", api.StatusReasonInvalid) } + if !IsBadRequest(NewBadRequest("reason")) { + t.Errorf("expected to be %s", api.StatusReasonBadRequest) + } + if !IsMethodNotSupported(NewMethodNotSupported("foo", "delete")) { + t.Errorf("expected to be %s", api.StatusReasonMethodNotAllowed) + } } func TestNewInvalid(t *testing.T) { diff --git a/pkg/api/types.go b/pkg/api/types.go index 427afc1cfd0..b30de6c32c5 100644 --- a/pkg/api/types.go +++ b/pkg/api/types.go @@ -931,6 +931,11 @@ const ( // data was invalid. API calls that return BadRequest can never succeed. StatusReasonBadRequest StatusReason = "BadRequest" + // StatusReasonMethodNotAllowed means that the action the client attempted to perform on the + // resource was not supported by the code - for instance, attempting to delete a resource that + // can only be created. API calls that return MethodNotAllowed can never succeed. + StatusReasonMethodNotAllowed StatusReason = "MethodNotAllowed" + // StatusReasonInternalError indicates that an internal error occurred, it is unexpected // and the outcome of the call is unknown. // Details (optional):