From 8878f20c6d0b06646843ce75d06027a8b9393ff2 Mon Sep 17 00:00:00 2001 From: Zhou Xing and Hua Zhang Date: Fri, 5 Jun 2015 08:13:44 +0800 Subject: [PATCH] implement the story of delete service instance that has keys [#92185380] https://www.pivotaltracker.com/story/show/92185380 --- cf/api/resources/service_instances.go | 6 ++++++ cf/api/services.go | 4 ++-- cf/api/services_test.go | 28 ++++++++++++++++++++++++-- cf/errors/service_association_error.go | 16 +++++++++++++++ cf/i18n/resources/de_DE.all.json | 5 +++++ cf/i18n/resources/en_US.all.json | 5 +++++ cf/i18n/resources/es_ES.all.json | 5 +++++ cf/i18n/resources/fr_FR.all.json | 5 +++++ cf/i18n/resources/it_IT.all.json | 5 +++++ cf/i18n/resources/ja_JA.all.json | 5 +++++ cf/i18n/resources/pt_BR.all.json | 5 +++++ cf/i18n/resources/zh_Hans.all.json | 5 +++++ cf/i18n/resources/zh_Hant.all.json | 5 +++++ cf/models/service_instance.go | 1 + 14 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 cf/errors/service_association_error.go diff --git a/cf/api/resources/service_instances.go b/cf/api/resources/service_instances.go index c628fc27ba7..b5653034815 100644 --- a/cf/api/resources/service_instances.go +++ b/cf/api/resources/service_instances.go @@ -22,6 +22,7 @@ type ServiceInstanceEntity struct { Name string DashboardUrl string `json:"dashboard_url"` ServiceBindings []ServiceBindingResource `json:"service_bindings"` + ServiceKeys []ServiceKeyResource `json:"service_keys"` ServicePlan ServicePlanResource `json:"service_plan"` LastOperation LastOperation `json:"last_operation"` } @@ -47,5 +48,10 @@ func (resource ServiceInstanceResource) ToModel() (instance models.ServiceInstan for _, bindingResource := range resource.Entity.ServiceBindings { instance.ServiceBindings = append(instance.ServiceBindings, bindingResource.ToFields()) } + + instance.ServiceKeys = []models.ServiceKeyFields{} + for _, keyResource := range resource.Entity.ServiceKeys { + instance.ServiceKeys = append(instance.ServiceKeys, keyResource.ToFields()) + } return } diff --git a/cf/api/services.go b/cf/api/services.go index 593261d8164..c11f68eb3c8 100644 --- a/cf/api/services.go +++ b/cf/api/services.go @@ -189,8 +189,8 @@ func (repo CloudControllerServiceRepository) RenameService(instance models.Servi } func (repo CloudControllerServiceRepository) DeleteService(instance models.ServiceInstance) (apiErr error) { - if len(instance.ServiceBindings) > 0 { - return errors.New("Cannot delete service instance, apps are still bound to it") + if len(instance.ServiceBindings) > 0 || len(instance.ServiceKeys) > 0 { + return errors.NewServiceAssociationError() } path := fmt.Sprintf("/v2/service_instances/%s?%s", instance.Guid, "accepts_incomplete=true") return repo.gateway.DeleteResource(repo.config.ApiEndpoint(), path) diff --git a/cf/api/services_test.go b/cf/api/services_test.go index ba3986c071d..a2839d9da38 100644 --- a/cf/api/services_test.go +++ b/cf/api/services_test.go @@ -435,7 +435,7 @@ var _ = Describe("Services Repo", func() { }) Describe("DeleteService", func() { - It("it deletes the service when no apps are bound", func() { + It("deletes the service when no apps and keys are bound", func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "DELETE", Path: "/v2/service_instances/my-service-instance-guid?accepts_incomplete=true&async=true", @@ -467,7 +467,31 @@ var _ = Describe("Services Repo", func() { } err := repo.DeleteService(serviceInstance) - Expect(err.Error()).To(Equal("Cannot delete service instance, apps are still bound to it")) + Expect(err).To(HaveOccurred()) + Expect(err).To(BeAssignableToTypeOf(&errors.ServiceAssociationError{})) + }) + + It("doesn't delete the service when keys are bound", func() { + setupTestServer() + + serviceInstance := models.ServiceInstance{} + serviceInstance.Guid = "my-service-instance-guid" + serviceInstance.ServiceKeys = []models.ServiceKeyFields{ + { + Name: "fake-service-key-1", + Url: "/v2/service_keys/service-key-1-guid", + Guid: "service-key-1-guid", + }, + { + Name: "fake-service-key-2", + Url: "/v2/service_keys/service-key-2-guid", + Guid: "service-key-2-guid", + }, + } + + err := repo.DeleteService(serviceInstance) + Expect(err).To(HaveOccurred()) + Expect(err).To(BeAssignableToTypeOf(&errors.ServiceAssociationError{})) }) }) diff --git a/cf/errors/service_association_error.go b/cf/errors/service_association_error.go new file mode 100644 index 00000000000..b263facf423 --- /dev/null +++ b/cf/errors/service_association_error.go @@ -0,0 +1,16 @@ +package errors + +import ( + . "github.com/cloudfoundry/cli/cf/i18n" +) + +type ServiceAssociationError struct { +} + +func NewServiceAssociationError() error { + return &ServiceAssociationError{} +} + +func (err *ServiceAssociationError) Error() string { + return T("Cannot delete service instance, service keys and bindings must first be deleted") +} diff --git a/cf/i18n/resources/de_DE.all.json b/cf/i18n/resources/de_DE.all.json index e2e7a213102..0094a617ed1 100644 --- a/cf/i18n/resources/de_DE.all.json +++ b/cf/i18n/resources/de_DE.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "Cannot delete service instance, service keys and bindings must first be deleted", + "modified": false } ] \ No newline at end of file diff --git a/cf/i18n/resources/en_US.all.json b/cf/i18n/resources/en_US.all.json index a13a4545ff3..1ba0d99d26c 100644 --- a/cf/i18n/resources/en_US.all.json +++ b/cf/i18n/resources/en_US.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "Cannot delete service instance, service keys and bindings must first be deleted", + "modified": false } ] \ No newline at end of file diff --git a/cf/i18n/resources/es_ES.all.json b/cf/i18n/resources/es_ES.all.json index dc1baafa8de..5e8da7133a9 100644 --- a/cf/i18n/resources/es_ES.all.json +++ b/cf/i18n/resources/es_ES.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instancias", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "Cannot delete service instance, service keys and bindings must first be deleted", + "modified": false } ] \ No newline at end of file diff --git a/cf/i18n/resources/fr_FR.all.json b/cf/i18n/resources/fr_FR.all.json index 2683a6c850e..a0ce7a487db 100644 --- a/cf/i18n/resources/fr_FR.all.json +++ b/cf/i18n/resources/fr_FR.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "Impossible de supprimer instance de service , clés de service et fixations doivent d'abord être supprimées", + "modified": false } ] \ No newline at end of file diff --git a/cf/i18n/resources/it_IT.all.json b/cf/i18n/resources/it_IT.all.json index 75a9e8bab54..dc13872bf73 100644 --- a/cf/i18n/resources/it_IT.all.json +++ b/cf/i18n/resources/it_IT.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "Cannot delete service instance, service keys and bindings must first be deleted", + "modified": false } ] \ No newline at end of file diff --git a/cf/i18n/resources/ja_JA.all.json b/cf/i18n/resources/ja_JA.all.json index 75a9e8bab54..dc13872bf73 100644 --- a/cf/i18n/resources/ja_JA.all.json +++ b/cf/i18n/resources/ja_JA.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "Cannot delete service instance, service keys and bindings must first be deleted", + "modified": false } ] \ No newline at end of file diff --git a/cf/i18n/resources/pt_BR.all.json b/cf/i18n/resources/pt_BR.all.json index fe038c61e6c..cdba7fdb819 100644 --- a/cf/i18n/resources/pt_BR.all.json +++ b/cf/i18n/resources/pt_BR.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instâncias", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "Cannot delete service instance, service keys and bindings must first be deleted", + "modified": false } ] \ No newline at end of file diff --git a/cf/i18n/resources/zh_Hans.all.json b/cf/i18n/resources/zh_Hans.all.json index 706e7aa213c..a9ab6eeb256 100644 --- a/cf/i18n/resources/zh_Hans.all.json +++ b/cf/i18n/resources/zh_Hans.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} 乘以 {{.InstanceCount}}实例数", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "无法删除服务实例,需要先删除服务密钥和绑定", + "modified": false } ] \ No newline at end of file diff --git a/cf/i18n/resources/zh_Hant.all.json b/cf/i18n/resources/zh_Hant.all.json index e2e7a213102..0094a617ed1 100644 --- a/cf/i18n/resources/zh_Hant.all.json +++ b/cf/i18n/resources/zh_Hant.all.json @@ -5303,5 +5303,10 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Cannot delete service instance, service keys and bindings must first be deleted", + "translation": "Cannot delete service instance, service keys and bindings must first be deleted", + "modified": false } ] \ No newline at end of file diff --git a/cf/models/service_instance.go b/cf/models/service_instance.go index a8df2153e50..760832aa03b 100644 --- a/cf/models/service_instance.go +++ b/cf/models/service_instance.go @@ -31,6 +31,7 @@ type ServiceInstanceFields struct { type ServiceInstance struct { ServiceInstanceFields ServiceBindings []ServiceBindingFields + ServiceKeys []ServiceKeyFields ServicePlan ServicePlanFields ServiceOffering ServiceOfferingFields }