diff --git a/api/cloudcontroller/ccerror/service_instance_already_shared_error.go b/api/cloudcontroller/ccerror/service_instance_already_shared_error.go new file mode 100644 index 00000000000..9ff9c812b3c --- /dev/null +++ b/api/cloudcontroller/ccerror/service_instance_already_shared_error.go @@ -0,0 +1,11 @@ +package ccerror + +// ServiceInstanceAlreadySharedError is returned when a +// service instance is already shared. +type ServiceInstanceAlreadySharedError struct { + Message string +} + +func (e ServiceInstanceAlreadySharedError) Error() string { + return e.Message +} diff --git a/api/cloudcontroller/ccv3/errors.go b/api/cloudcontroller/ccv3/errors.go index c89a60d126a..e819b980a40 100644 --- a/api/cloudcontroller/ccv3/errors.go +++ b/api/cloudcontroller/ccv3/errors.go @@ -154,6 +154,7 @@ func handleUnprocessableEntity(errorResponse ccerror.V3Error) error { roleExistsRegexp := regexp.MustCompile(`User '.*' already has '.*' role.*`) quotaExistsRegexp := regexp.MustCompile(`.* Quota '.*' already exists\.`) securityGroupExistsRegexp := regexp.MustCompile(`Security group with name '.*' already exists\.`) + serviceInstanceSharedRegexp := regexp.MustCompile(`A service instance called .* has already been shared with .*\.`) // boolean switch case with partial/regex string matchers switch { @@ -174,6 +175,8 @@ func handleUnprocessableEntity(errorResponse ccerror.V3Error) error { case strings.Contains(errorString, "The service instance name is taken"): return ccerror.ServiceInstanceNameTakenError{Message: err.Message} + case serviceInstanceSharedRegexp.MatchString(errorString): + return ccerror.ServiceInstanceAlreadySharedError{Message: err.Message} case orgNameTakenRegexp.MatchString(errorString): return ccerror.OrganizationNameTakenError{UnprocessableEntityError: err} case roleExistsRegexp.MatchString(errorString): diff --git a/api/cloudcontroller/ccv3/errors_test.go b/api/cloudcontroller/ccv3/errors_test.go index b673ab35370..0fe7c021b4a 100644 --- a/api/cloudcontroller/ccv3/errors_test.go +++ b/api/cloudcontroller/ccv3/errors_test.go @@ -507,6 +507,27 @@ var _ = Describe("Error Wrapper", func() { }) }) + When("the service instance has already been shared", func() { + BeforeEach(func() { + serverResponse = ` +{ + "errors": [ + { + "code": 10008, + "detail": "A service instance called foo has already been shared with foo-space.", + "title": "CF-UnprocessableEntity" + } + ] +}` + }) + + It("returns an ServiceInstanceAlreadySharedError", func() { + Expect(makeError).To(MatchError(ccerror.ServiceInstanceAlreadySharedError{ + Message: "A service instance called foo has already been shared with foo-space.", + })) + }) + }) + When("the buildpack is invalid", func() { BeforeEach(func() { serverResponse = ` diff --git a/command/v7/share_service_command.go b/command/v7/share_service_command.go index fdf72c1ad50..cf0a8bdd40b 100644 --- a/command/v7/share_service_command.go +++ b/command/v7/share_service_command.go @@ -2,6 +2,7 @@ package v7 import ( "code.cloudfoundry.org/cli/actor/v7action" + "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" "code.cloudfoundry.org/cli/command/flag" "code.cloudfoundry.org/cli/types" ) @@ -38,7 +39,14 @@ func (cmd ShareServiceCommand) Execute(args []string) error { }) cmd.UI.DisplayWarnings(warnings) - if err != nil { + + switch err.(type) { + case nil: + case ccerror.ServiceInstanceAlreadySharedError: + cmd.UI.DisplayOK() + cmd.UI.DisplayTextWithFlavor("A service instance called {{.ServiceInstanceName}} has already been shared", map[string]interface{}{"ServiceInstanceName": cmd.RequiredArgs.ServiceInstance}) + return nil + default: return err } diff --git a/command/v7/share_service_command_test.go b/command/v7/share_service_command_test.go index b9f5a503284..2b2315042ce 100644 --- a/command/v7/share_service_command_test.go +++ b/command/v7/share_service_command_test.go @@ -3,6 +3,7 @@ package v7_test import ( "errors" + "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" "code.cloudfoundry.org/cli/util/configv3" "code.cloudfoundry.org/cli/command/flag" @@ -141,6 +142,23 @@ var _ = Describe("share-service command", func() { }) }) + When("the service instance is already shared", func() { + BeforeEach(func() { + fakeActor.ShareServiceInstanceToSpaceAndOrgReturns(v7action.Warnings{"warning one", "warning two"}, ccerror.ServiceInstanceAlreadySharedError{}) + }) + + It("succeeds, displaying warnings, 'OK' and an informative message", func() { + Expect(executeErr).NotTo(HaveOccurred()) + + Expect(testUI.Out).To(Say(`OK`)) + Expect(testUI.Err).To(SatisfyAll( + Say("warning one"), + Say("warning two"), + )) + Expect(testUI.Out).To(Say("A service instance called %s has already been shared", expectedServiceInstanceName)) + }) + }) + When("the actor errors", func() { BeforeEach(func() { fakeSharedActor.CheckTargetReturns(nil)