diff --git a/cf/api/fakes/fake_service_key_repo.go b/cf/api/fakes/fake_service_key_repo.go new file mode 100644 index 00000000000..227270b01cc --- /dev/null +++ b/cf/api/fakes/fake_service_key_repo.go @@ -0,0 +1,25 @@ +package fakes + +type FakeServiceKeyRepo struct { + CreateServiceKeyError error + + CreateServiceKeyArgs CreateServiceKeyArgsType +} + +type CreateServiceKeyArgsType struct { + ServiceInstanceId string + ServiceKeyName string +} + +func NewFakeServiceKeyRepo() *FakeServiceKeyRepo { + return &FakeServiceKeyRepo{ + CreateServiceKeyArgs: CreateServiceKeyArgsType{}, + } +} + +func (f *FakeServiceKeyRepo) CreateServiceKey(instanceId string, serviceKeyName string) (apiErr error) { + f.CreateServiceKeyArgs.ServiceInstanceId = instanceId + f.CreateServiceKeyArgs.ServiceKeyName = serviceKeyName + + return f.CreateServiceKeyError +} diff --git a/cf/api/repository_locator.go b/cf/api/repository_locator.go index 910b1e870a4..b9172f2c839 100644 --- a/cf/api/repository_locator.go +++ b/cf/api/repository_locator.go @@ -50,6 +50,7 @@ type RepositoryLocator struct { routeRepo CloudControllerRouteRepository stackRepo stacks.CloudControllerStackRepository serviceRepo CloudControllerServiceRepository + serviceKeyRepo CloudControllerServiceKeyRepository serviceBindingRepo CloudControllerServiceBindingRepository serviceSummaryRepo CloudControllerServiceSummaryRepository userRepo CloudControllerUserRepository @@ -111,6 +112,7 @@ func NewRepositoryLocator(config core_config.ReadWriter, gatewaysByName map[stri loc.routeRepo = NewCloudControllerRouteRepository(config, cloudControllerGateway) loc.stackRepo = stacks.NewCloudControllerStackRepository(config, cloudControllerGateway) loc.serviceRepo = NewCloudControllerServiceRepository(config, cloudControllerGateway) + loc.serviceKeyRepo = NewCloudControllerServiceKeyRepository(config, cloudControllerGateway) loc.serviceBindingRepo = NewCloudControllerServiceBindingRepository(config, cloudControllerGateway) loc.serviceBrokerRepo = NewCloudControllerServiceBrokerRepository(config, cloudControllerGateway) loc.servicePlanRepo = NewCloudControllerServicePlanRepository(config, cloudControllerGateway) @@ -196,6 +198,10 @@ func (locator RepositoryLocator) GetServiceRepository() ServiceRepository { return locator.serviceRepo } +func (locator RepositoryLocator) GetServiceKeyRepository() ServiceKeyRepository { + return locator.serviceKeyRepo +} + func (locator RepositoryLocator) GetServiceBindingRepository() ServiceBindingRepository { return locator.serviceBindingRepo } diff --git a/cf/api/service_keys.go b/cf/api/service_keys.go new file mode 100644 index 00000000000..ba21f115586 --- /dev/null +++ b/cf/api/service_keys.go @@ -0,0 +1,41 @@ +package api + +import ( + "fmt" + "strings" + + "github.com/cloudfoundry/cli/cf/configuration/core_config" + "github.com/cloudfoundry/cli/cf/errors" + "github.com/cloudfoundry/cli/cf/net" +) + +type ServiceKeyRepository interface { + CreateServiceKey(instanceId string, keyName string) (apiErr error) +} + +type CloudControllerServiceKeyRepository struct { + config core_config.Reader + gateway net.Gateway +} + +func NewCloudControllerServiceKeyRepository(config core_config.Reader, gateway net.Gateway) (repo CloudControllerServiceKeyRepository) { + return CloudControllerServiceKeyRepository{ + config: config, + gateway: gateway, + } +} + +func (c CloudControllerServiceKeyRepository) CreateServiceKey(instanceId string, keyName string) (apiErr error) { + path := "/v2/service_keys" + data := fmt.Sprintf(`{"service_instance_guid":"%s","name":"%s"}`, instanceId, keyName) + + err := c.gateway.CreateResource(c.config.ApiEndpoint(), path, strings.NewReader(data)) + + if httpErr, ok := err.(errors.HttpError); ok && httpErr.ErrorCode() == errors.SERVICE_KEY_NAME_TAKEN { + return errors.NewModelAlreadyExistsError("Service key", keyName) + } else if httpErr, ok := err.(errors.HttpError); ok && httpErr.ErrorCode() == errors.UNBINDABLE_SERVICE { + return errors.NewUnbindableServiceError() + } + + return nil +} diff --git a/cf/api/service_keys_test.go b/cf/api/service_keys_test.go new file mode 100644 index 00000000000..c257ad80298 --- /dev/null +++ b/cf/api/service_keys_test.go @@ -0,0 +1,78 @@ +package api_test + +import ( + "net/http" + "net/http/httptest" + "time" + + testapi "github.com/cloudfoundry/cli/cf/api/fakes" + testconfig "github.com/cloudfoundry/cli/testhelpers/configuration" + testnet "github.com/cloudfoundry/cli/testhelpers/net" + testterm "github.com/cloudfoundry/cli/testhelpers/terminal" + + "github.com/cloudfoundry/cli/cf/configuration/core_config" + "github.com/cloudfoundry/cli/cf/errors" + "github.com/cloudfoundry/cli/cf/net" + + . "github.com/cloudfoundry/cli/cf/api" + . "github.com/cloudfoundry/cli/testhelpers/matchers" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Service Keys Repo", func() { + var ( + testServer *httptest.Server + testHandler *testnet.TestHandler + configRepo core_config.ReadWriter + repo ServiceKeyRepository + ) + + setupTestServer := func(reqs ...testnet.TestRequest) { + testServer, testHandler = testnet.NewServer(reqs) + configRepo.SetApiEndpoint(testServer.URL) + } + + BeforeEach(func() { + configRepo = testconfig.NewRepositoryWithDefaults() + configRepo.SetAccessToken("BEARER my_access_token") + + gateway := net.NewCloudControllerGateway(configRepo, time.Now, &testterm.FakeUI{}) + repo = NewCloudControllerServiceKeyRepository(configRepo, gateway) + }) + + Describe("creating a service key", func() { + It("makes the right request", func() { + setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ + Method: "POST", + Path: "/v2/service_keys", + Matcher: testnet.RequestBodyMatcher(`{"service_instance_guid": "fake-instance-guid", "name": "fake-key-name"}`), + Response: testnet.TestResponse{Status: http.StatusCreated}, + })) + + err := repo.CreateServiceKey("fake-instance-guid", "fake-key-name") + Expect(testHandler).To(HaveAllRequestsCalled()) + Expect(err).NotTo(HaveOccurred()) + }) + + It("returns a ModelAlreadyExistsError if the service key exists", func() { + setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ + Method: "POST", + Path: "/v2/service_keys", + Matcher: testnet.RequestBodyMatcher(`{"service_instance_guid":"fake-instance-guid","name":"exist-service-key"}`), + Response: testnet.TestResponse{ + Status: http.StatusBadRequest, + Body: `{"code":60003,"description":"The service key name is taken: exist-service-key"}`}, + })) + + err := repo.CreateServiceKey("fake-instance-guid", "exist-service-key") + Expect(testHandler).To(HaveAllRequestsCalled()) + Expect(err).To(BeAssignableToTypeOf(&errors.ModelAlreadyExistsError{})) + }) + }) + + AfterEach(func() { + testServer.Close() + }) +}) diff --git a/cf/app/help.go b/cf/app/help.go index 4702c614f56..da1088b0b25 100644 --- a/cf/app/help.go +++ b/cf/app/help.go @@ -156,6 +156,8 @@ func newAppPresenter(app *cli.App) (presenter appPresenter) { presentCommand("update-service"), presentCommand("delete-service"), presentCommand("rename-service"), + }, { + presentCommand("create-service-key"), }, { presentCommand("bind-service"), presentCommand("unbind-service"), diff --git a/cf/command_factory/factory.go b/cf/command_factory/factory.go index ad2d4ad2735..a74f08391f5 100644 --- a/cf/command_factory/factory.go +++ b/cf/command_factory/factory.go @@ -35,6 +35,7 @@ import ( "github.com/cloudfoundry/cli/cf/commands/serviceaccess" "github.com/cloudfoundry/cli/cf/commands/serviceauthtoken" "github.com/cloudfoundry/cli/cf/commands/servicebroker" + "github.com/cloudfoundry/cli/cf/commands/servicekey" "github.com/cloudfoundry/cli/cf/commands/space" "github.com/cloudfoundry/cli/cf/commands/spacequota" "github.com/cloudfoundry/cli/cf/commands/user" @@ -100,6 +101,7 @@ func NewFactory(ui terminal.UI, config core_config.ReadWriter, manifestRepo mani factory.cmdsByName["create-service-auth-token"] = serviceauthtoken.NewCreateServiceAuthToken(ui, config, repoLocator.GetServiceAuthTokenRepository()) factory.cmdsByName["create-service-broker"] = servicebroker.NewCreateServiceBroker(ui, config, repoLocator.GetServiceBrokerRepository()) + factory.cmdsByName["create-service-key"] = servicekey.NewCreateServiceKey(ui, config, repoLocator.GetServiceRepository(), repoLocator.GetServiceKeyRepository()) factory.cmdsByName["create-user"] = user.NewCreateUser(ui, config, repoLocator.GetUserRepository()) factory.cmdsByName["create-user-provided-service"] = service.NewCreateUserProvidedService(ui, config, repoLocator.GetUserProvidedServiceInstanceRepository()) factory.cmdsByName["curl"] = commands.NewCurl(ui, config, repoLocator.GetCurlRepository()) diff --git a/cf/commands/servicekey/create_service_key.go b/cf/commands/servicekey/create_service_key.go new file mode 100644 index 00000000000..0bb123f68a0 --- /dev/null +++ b/cf/commands/servicekey/create_service_key.go @@ -0,0 +1,89 @@ +package servicekey + +import ( + "github.com/cloudfoundry/cli/cf/api" + "github.com/cloudfoundry/cli/cf/command_metadata" + "github.com/cloudfoundry/cli/cf/configuration/core_config" + "github.com/cloudfoundry/cli/cf/errors" + "github.com/cloudfoundry/cli/cf/requirements" + "github.com/cloudfoundry/cli/cf/terminal" + "github.com/codegangsta/cli" + + . "github.com/cloudfoundry/cli/cf/i18n" +) + +type CreateServiceKey struct { + ui terminal.UI + config core_config.Reader + serviceRepo api.ServiceRepository + serviceKeyRepo api.ServiceKeyRepository +} + +func NewCreateServiceKey(ui terminal.UI, config core_config.Reader, serviceRepo api.ServiceRepository, serviceKeyRepo api.ServiceKeyRepository) (cmd CreateServiceKey) { + return CreateServiceKey{ + ui: ui, + config: config, + serviceRepo: serviceRepo, + serviceKeyRepo: serviceKeyRepo, + } +} + +func (cmd CreateServiceKey) Metadata() command_metadata.CommandMetadata { + return command_metadata.CommandMetadata{ + Name: "create-service-key", + ShortName: "csk", + Description: T("Create key for a service instance"), + Usage: T(`CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY + +EXAMPLE: + CF_NAME create-service-key mydb mykey`), + } +} + +func (cmd CreateServiceKey) GetRequirements(requirementsFactory requirements.Factory, c *cli.Context) (reqs []requirements.Requirement, err error) { + if len(c.Args()) != 2 { + cmd.ui.FailWithUsage(c) + } + + loginRequirement := requirementsFactory.NewLoginRequirement() + serviceInstanceRequirement := requirementsFactory.NewServiceInstanceRequirement(c.Args()[0]) + targetSpaceRequirement := requirementsFactory.NewTargetedSpaceRequirement() + + reqs = []requirements.Requirement{loginRequirement, serviceInstanceRequirement, targetSpaceRequirement} + + return reqs, nil +} + +func (cmd CreateServiceKey) Run(c *cli.Context) { + serviceInstanceName := c.Args()[0] + serviceKeyName := c.Args()[1] + + cmd.ui.Say(T("Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + map[string]interface{}{ + "ServiceInstanceName": terminal.EntityNameColor(serviceInstanceName), + "ServiceKeyName": terminal.EntityNameColor(serviceKeyName), + "CurrentUser": terminal.EntityNameColor(cmd.config.Username()), + })) + + serviceInstance, err := cmd.serviceRepo.FindInstanceByName(serviceInstanceName) + if err != nil { + cmd.ui.Failed(err.Error()) + return + } + + err = cmd.serviceKeyRepo.CreateServiceKey(serviceInstance.Guid, serviceKeyName) + if err != nil { + cmd.ui.Failed(err.Error()) + return + } + + switch err.(type) { + case nil: + cmd.ui.Ok() + case *errors.ModelAlreadyExistsError: + cmd.ui.Ok() + cmd.ui.Warn(err.Error()) + default: + cmd.ui.Failed(err.Error()) + } +} diff --git a/cf/commands/servicekey/create_service_key_test.go b/cf/commands/servicekey/create_service_key_test.go new file mode 100644 index 00000000000..ac878957801 --- /dev/null +++ b/cf/commands/servicekey/create_service_key_test.go @@ -0,0 +1,104 @@ +package servicekey_test + +import ( + "github.com/cloudfoundry/cli/cf/configuration/core_config" + "github.com/cloudfoundry/cli/cf/errors" + "github.com/cloudfoundry/cli/cf/models" + "github.com/cloudfoundry/cli/generic" + + testapi "github.com/cloudfoundry/cli/cf/api/fakes" + testcmd "github.com/cloudfoundry/cli/testhelpers/commands" + testconfig "github.com/cloudfoundry/cli/testhelpers/configuration" + testreq "github.com/cloudfoundry/cli/testhelpers/requirements" + testterm "github.com/cloudfoundry/cli/testhelpers/terminal" + + . "github.com/cloudfoundry/cli/cf/commands/servicekey" + . "github.com/cloudfoundry/cli/testhelpers/matchers" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("create-service-key command", func() { + var ( + ui *testterm.FakeUI + config core_config.Repository + cmd CreateServiceKey + requirementsFactory *testreq.FakeReqFactory + serviceRepo *testapi.FakeServiceRepo + serviceKeyRepo *testapi.FakeServiceKeyRepo + ) + + BeforeEach(func() { + ui = &testterm.FakeUI{} + config = testconfig.NewRepositoryWithDefaults() + serviceRepo = &testapi.FakeServiceRepo{} + serviceInstance := models.ServiceInstance{} + serviceInstance.Guid = "fake-instance-guid" + serviceRepo.FindInstanceByNameMap = generic.NewMap() + serviceRepo.FindInstanceByNameMap.Set("fake-service-instance", serviceInstance) + serviceKeyRepo = testapi.NewFakeServiceKeyRepo() + cmd = NewCreateServiceKey(ui, config, serviceRepo, serviceKeyRepo) + requirementsFactory = &testreq.FakeReqFactory{LoginSuccess: true, TargetedSpaceSuccess: true, ServiceInstanceNotFound: false} + }) + + var callCreateService = func(args []string) bool { + return testcmd.RunCommand(cmd, args, requirementsFactory) + } + + Describe("requirements", func() { + It("fails when not logged in", func() { + requirementsFactory = &testreq.FakeReqFactory{LoginSuccess: false} + Expect(callCreateService([]string{"fake-service-instance", "fake-service-key"})).To(BeFalse()) + }) + + It("requires two arguments to run", func() { + Expect(callCreateService([]string{})).To(BeFalse()) + Expect(callCreateService([]string{"fake-arg-one"})).To(BeFalse()) + Expect(callCreateService([]string{"fake-arg-one", "fake-arg-two", "fake-arg-three"})).To(BeFalse()) + }) + + It("fails when service instance is not found", func() { + requirementsFactory = &testreq.FakeReqFactory{LoginSuccess: true, ServiceInstanceNotFound: true} + Expect(callCreateService([]string{"non-exist-service-instance", "fake-service-key"})).To(BeFalse()) + }) + + It("fails when space is not targetted", func() { + requirementsFactory = &testreq.FakeReqFactory{LoginSuccess: true, TargetedSpaceSuccess: false} + Expect(callCreateService([]string{"non-exist-service-instance", "fake-service-key"})).To(BeFalse()) + }) + }) + + Describe("requiremnts are satisfied", func() { + It("create service key successfully", func() { + callCreateService([]string{"fake-service-instance", "fake-service-key"}) + + Expect(ui.Outputs).To(ContainSubstrings( + []string{"Creating service key", "fake-service-key", "for service instance", "fake-service-instance", "as", "my-user"}, + []string{"OK"}, + )) + Expect(serviceKeyRepo.CreateServiceKeyArgs.ServiceInstanceId).To(Equal("fake-instance-guid")) + Expect(serviceKeyRepo.CreateServiceKeyArgs.ServiceKeyName).To(Equal("fake-service-key")) + }) + + It("create service key failed when the service key already exists", func() { + serviceKeyRepo.CreateServiceKeyError = errors.NewModelAlreadyExistsError("ServiceKey", "exist-service-key") + callCreateService([]string{"fake-service-instance", "exist-service-key"}) + + Expect(ui.Outputs).To(ContainSubstrings( + []string{"Creating service key", "exist-service-key", "for service instance", "fake-service-instance", "as", "my-user"}, + []string{"FAILED"}, + []string{"ServiceKey exist-service-key already exists"})) + }) + + It("create service key failed when the service is unbindable", func() { + serviceKeyRepo.CreateServiceKeyError = errors.NewUnbindableServiceError() + callCreateService([]string{"fake-service-instance", "exist-service-key"}) + + Expect(ui.Outputs).To(ContainSubstrings( + []string{"Creating service key", "exist-service-key", "for service instance", "fake-service-instance", "as", "my-user"}, + []string{"FAILED"}, + []string{"This service doesn't support creation of keys."})) + }) + }) +}) diff --git a/cf/commands/servicekey/servicekey_suite_test.go b/cf/commands/servicekey/servicekey_suite_test.go new file mode 100644 index 00000000000..bdaab4dbbe4 --- /dev/null +++ b/cf/commands/servicekey/servicekey_suite_test.go @@ -0,0 +1,20 @@ +package servicekey_test + +import ( + "testing" + + "github.com/cloudfoundry/cli/cf/i18n" + "github.com/cloudfoundry/cli/cf/i18n/detection" + "github.com/cloudfoundry/cli/testhelpers/configuration" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestServicekey(t *testing.T) { + config := configuration.NewRepositoryWithDefaults() + i18n.T = i18n.Init(config, &detection.JibberJabberDetector{}) + + RegisterFailHandler(Fail) + RunSpecs(t, "Servicekey Suite") +} diff --git a/cf/errors/known_error_codes.go b/cf/errors/known_error_codes.go index 78a713f6e10..705a84e7560 100644 --- a/cf/errors/known_error_codes.go +++ b/cf/errors/known_error_codes.go @@ -10,9 +10,11 @@ const ( SPACE_EXISTS = "40002" QUOTA_EXISTS = "240002" SERVICE_INSTANCE_NAME_TAKEN = "60002" + SERVICE_KEY_NAME_TAKEN = "60003" APP_NOT_STAGED = "170002" APP_STOPPED = "220001" BUILDPACK_EXISTS = "290001" SECURITY_GROUP_EXISTS = "300005" APP_ALREADY_BOUND = "90003" + UNBINDABLE_SERVICE = "90005" ) diff --git a/cf/errors/unbindable_service_error.go b/cf/errors/unbindable_service_error.go new file mode 100644 index 00000000000..7362e094101 --- /dev/null +++ b/cf/errors/unbindable_service_error.go @@ -0,0 +1,16 @@ +package errors + +import ( + . "github.com/cloudfoundry/cli/cf/i18n" +) + +type UnbindableServiceError struct { +} + +func NewUnbindableServiceError() error { + return &UnbindableServiceError{} +} + +func (err *UnbindableServiceError) Error() string { + return T("This service doesn't support creation of keys.") +} diff --git a/cf/i18n/resources/de_DE.all.json b/cf/i18n/resources/de_DE.all.json index 1ecf4a4739d..39f4abc51aa 100644 --- a/cf/i18n/resources/de_DE.all.json +++ b/cf/i18n/resources/de_DE.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "Create key for a service instance", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "translation": "This service doesn't support creation of keys.", + "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 a2b817ea937..2cde95af53a 100644 --- a/cf/i18n/resources/en_US.all.json +++ b/cf/i18n/resources/en_US.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "Create key for a service instance", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "translation": "This service doesn't support creation of keys.", + "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 a882a006b81..3e85ff319b3 100644 --- a/cf/i18n/resources/es_ES.all.json +++ b/cf/i18n/resources/es_ES.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instancias", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "Create key for a service instance", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "translation": "This service doesn't support creation of keys.", + "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 115240ac9df..301488be713 100644 --- a/cf/i18n/resources/fr_FR.all.json +++ b/cf/i18n/resources/fr_FR.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "Create key for a service instance", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "translation": "Ce service ne supporte pas la création de clefs.", + "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 f65b71d4bc3..10229f80a18 100644 --- a/cf/i18n/resources/it_IT.all.json +++ b/cf/i18n/resources/it_IT.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "Create key for a service instance", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "translation": "This service doesn't support creation of keys.", + "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 91b0131089b..75b562b9dae 100644 --- a/cf/i18n/resources/ja_JA.all.json +++ b/cf/i18n/resources/ja_JA.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "Create key for a service instance", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "translation": "This service doesn't support creation of keys.", + "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 da8497284a6..b18b7c629ae 100644 --- a/cf/i18n/resources/pt_BR.all.json +++ b/cf/i18n/resources/pt_BR.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instâncias", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "Create key for a service instance", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "translation": "This service doesn't support creation of keys.", + "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 c00f6b477d6..f5299efcc13 100644 --- a/cf/i18n/resources/zh_Hans.all.json +++ b/cf/i18n/resources/zh_Hans.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} 乘以 {{.InstanceCount}}实例数", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "为服务实例创建密钥", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\n样例:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "用户{{.CurrentUser}}正在为服务实例{{.ServiceInstanceName}}创建名为{{.ServiceKeyName}}的密钥...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "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 1ecf4a4739d..39f4abc51aa 100644 --- a/cf/i18n/resources/zh_Hant.all.json +++ b/cf/i18n/resources/zh_Hant.all.json @@ -5163,5 +5163,55 @@ "id": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "translation": "{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances", "modified": false + }, + { + "id": "Share a private domain with an org", + "translation": "Share a private domain with an org", + "modified": false + }, + { + "id": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "translation": "Sharing domain {{.DomainName}} with org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME share-private-domain ORG DOMAIN", + "translation": "CF_NAME share-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Unshare a private domain with an org", + "translation": "Unshare a private domain with an org", + "modified": false + }, + { + "id": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "translation": "Unsharing domain {{.DomainName}} from org {{.OrgName}} as {{.Username}}...", + "modified": false + }, + { + "id": "CF_NAME unshare-private-domain ORG DOMAIN", + "translation": "CF_NAME unshare-private-domain ORG DOMAIN", + "modified": false + }, + { + "id": "Create key for a service instance", + "translation": "Create key for a service instance", + "modified": false + }, + { + "id": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "translation": "CF_NAME create-service-key SERVICE_INSTANCE SERVICE_KEY\n\nEXAMPLE:\n CF_NAME create-service-key mydb mykey", + "modified": false + }, + { + "id": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "translation": "Creating service key {{.ServiceKeyName}} for service instance {{.ServiceInstanceName}} as {{.CurrentUser}}...", + "modified": false + }, + { + "id": "This service doesn't support creation of keys.", + "translation": "This service doesn't support creation of keys.", + "modified": false } -] \ No newline at end of file +] diff --git a/testhelpers/requirements/fake_req_factory.go b/testhelpers/requirements/fake_req_factory.go index 9f3b5d322a2..7744cd05bca 100644 --- a/testhelpers/requirements/fake_req_factory.go +++ b/testhelpers/requirements/fake_req_factory.go @@ -19,6 +19,8 @@ type FakeReqFactory struct { TargetedOrgSuccess bool BuildpackSuccess bool + ServiceInstanceNotFound bool + SpaceName string Space models.Space @@ -51,7 +53,7 @@ func (f *FakeReqFactory) NewApplicationRequirement(name string) requirements.App func (f *FakeReqFactory) NewServiceInstanceRequirement(name string) requirements.ServiceInstanceRequirement { f.ServiceInstanceName = name - return FakeRequirement{f, true} + return FakeRequirement{f, !f.ServiceInstanceNotFound} } func (f *FakeReqFactory) NewLoginRequirement() requirements.Requirement {