Skip to content

Commit

Permalink
Add optional tags to create-service
Browse files Browse the repository at this point in the history
[#61861194]
  • Loading branch information
tanglisha authored and Greg Cobb and Liz Dahlstrom committed May 28, 2015
1 parent 5992630 commit dd5c171
Show file tree
Hide file tree
Showing 15 changed files with 115 additions and 23 deletions.
4 changes: 3 additions & 1 deletion cf/api/fakes/fake_service_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ type FakeServiceRepo struct {
Name string
PlanGuid string
Params map[string]interface{}
Tags []string
}
CreateServiceInstanceReturns struct {
Error error
Expand Down Expand Up @@ -141,10 +142,11 @@ func (repo *FakeServiceRepo) FindServiceOfferingsByLabel(name string) (offerings
return
}

func (repo *FakeServiceRepo) CreateServiceInstance(name, planGuid string, params map[string]interface{}) (apiErr error) {
func (repo *FakeServiceRepo) CreateServiceInstance(name, planGuid string, params map[string]interface{}, tags []string) (apiErr error) {
repo.CreateServiceInstanceArgs.Name = name
repo.CreateServiceInstanceArgs.PlanGuid = planGuid
repo.CreateServiceInstanceArgs.Params = params
repo.CreateServiceInstanceArgs.Tags = tags

return repo.CreateServiceInstanceReturns.Error
}
Expand Down
5 changes: 3 additions & 2 deletions cf/api/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type ServiceRepository interface {
GetAllServiceOfferings() (offerings models.ServiceOfferings, apiErr error)
GetServiceOfferingsForSpace(spaceGuid string) (offerings models.ServiceOfferings, apiErr error)
FindInstanceByName(name string) (instance models.ServiceInstance, apiErr error)
CreateServiceInstance(name, planGuid string, params map[string]interface{}) (apiErr error)
CreateServiceInstance(name, planGuid string, params map[string]interface{}, tags []string) (apiErr error)
UpdateServiceInstance(instanceGuid, planGuid string) (apiErr error)
RenameService(instance models.ServiceInstance, newName string) (apiErr error)
DeleteService(instance models.ServiceInstance) (apiErr error)
Expand Down Expand Up @@ -134,13 +134,14 @@ func (repo CloudControllerServiceRepository) FindInstanceByName(name string) (in
return
}

func (repo CloudControllerServiceRepository) CreateServiceInstance(name, planGuid string, params map[string]interface{}) (err error) {
func (repo CloudControllerServiceRepository) CreateServiceInstance(name, planGuid string, params map[string]interface{}, tags []string) (err error) {
path := "/v2/service_instances?accepts_incomplete=true"
request := models.ServiceInstanceRequest{
Name: name,
PlanGuid: planGuid,
SpaceGuid: repo.config.SpaceFields().Guid,
Params: params,
Tags: tags,
}

jsonBytes, err := json.Marshal(request)
Expand Down
27 changes: 22 additions & 5 deletions cf/api/services_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ var _ = Describe("Services Repo", func() {
Response: testnet.TestResponse{Status: http.StatusCreated},
}))

err := repo.CreateServiceInstance("instance-name", "plan-guid", nil)
err := repo.CreateServiceInstance("instance-name", "plan-guid", nil, nil)
Expect(testHandler).To(HaveAllRequestsCalled())
Expect(err).NotTo(HaveOccurred())
})
Expand All @@ -220,7 +220,7 @@ var _ = Describe("Services Repo", func() {
paramsMap := make(map[string]interface{})
paramsMap["data"] = "hello"

err := repo.CreateServiceInstance("instance-name", "plan-guid", paramsMap)
err := repo.CreateServiceInstance("instance-name", "plan-guid", paramsMap, nil)
Expect(testHandler).To(HaveAllRequestsCalled())
Expect(err).NotTo(HaveOccurred())
})
Expand All @@ -231,11 +231,28 @@ var _ = Describe("Services Repo", func() {
paramsMap := make(map[string]interface{})
paramsMap["data"] = make(chan bool)

err := repo.CreateServiceInstance("instance-name", "plan-guid", paramsMap)
err := repo.CreateServiceInstance("instance-name", "plan-guid", paramsMap, nil)
Expect(err).To(MatchError("json: unsupported type: chan bool"))
})
})

Context("when there are tags", func() {
It("sends the tags as part of the request body", func() {
setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{
Method: "POST",
Path: "/v2/service_instances?accepts_incomplete=true",
Matcher: testnet.RequestBodyMatcher(`{"name":"instance-name","service_plan_guid":"plan-guid","space_guid":"my-space-guid","tags": ["foo", "bar"]}`),
Response: testnet.TestResponse{Status: http.StatusCreated},
}))

tags := []string{"foo", "bar"}

err := repo.CreateServiceInstance("instance-name", "plan-guid", nil, tags)
Expect(testHandler).To(HaveAllRequestsCalled())
Expect(err).NotTo(HaveOccurred())
})
})

Context("when the name is taken but an identical service exists", func() {
BeforeEach(func() {
setupTestServer(
Expand All @@ -252,7 +269,7 @@ var _ = Describe("Services Repo", func() {
})

It("returns a ModelAlreadyExistsError if the plan is the same", func() {
err := repo.CreateServiceInstance("my-service", "plan-guid", nil)
err := repo.CreateServiceInstance("my-service", "plan-guid", nil, nil)
Expect(testHandler).To(HaveAllRequestsCalled())
Expect(err).To(BeAssignableToTypeOf(&errors.ModelAlreadyExistsError{}))
})
Expand All @@ -274,7 +291,7 @@ var _ = Describe("Services Repo", func() {
})

It("fails if the plan is different", func() {
err := repo.CreateServiceInstance("my-service", "different-plan-guid", nil)
err := repo.CreateServiceInstance("my-service", "different-plan-guid", nil, nil)

Expect(testHandler).To(HaveAllRequestsCalled())
Expect(err).To(HaveOccurred())
Expand Down
24 changes: 19 additions & 5 deletions cf/commands/service/create_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package service

import (
"encoding/json"
"strings"

"github.com/cloudfoundry/cli/cf/actors/service_builder"
"github.com/cloudfoundry/cli/cf/api"
Expand Down Expand Up @@ -37,15 +38,17 @@ func (cmd CreateService) Metadata() command_metadata.CommandMetadata {
Name: "create-service",
ShortName: "cs",
Description: T("Create a service instance"),
Usage: T(`CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE
Usage: T(`CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]
EXAMPLE:
CF_NAME create-service dbaas silver mydb
CF_NAME create-service dbaas silver mydb -t "list, of, tags"
TIP:
Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps`),
Flags: []cli.Flag{
flag_helpers.NewStringFlag("c", T("Valid JSON object containing service-specific configuration parameters, provided either in-line or in a file. For a list of supported configuration parameters, see documentation for the particular service offering.")),
flag_helpers.NewStringFlag("t", T("User provided tags")),
},
}
}
Expand All @@ -68,8 +71,10 @@ func (cmd CreateService) Run(c *cli.Context) {
planName := c.Args()[1]
serviceInstanceName := c.Args()[2]
params := c.String("c")
tags := c.String("t")

tagsList := cmd.parseTags(tags)

paramsMap := make(map[string]interface{})
paramsMap, err := cmd.parseArbitraryParams(params)
if err != nil && params != "" {
cmd.ui.Failed(T("Invalid JSON provided in -c argument"))
Expand All @@ -83,7 +88,7 @@ func (cmd CreateService) Run(c *cli.Context) {
"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
}))

plan, err := cmd.CreateService(serviceName, planName, serviceInstanceName, paramsMap)
plan, err := cmd.CreateService(serviceName, planName, serviceInstanceName, paramsMap, tagsList)

switch err.(type) {
case nil:
Expand All @@ -110,7 +115,7 @@ func (cmd CreateService) Run(c *cli.Context) {
}
}

func (cmd CreateService) CreateService(serviceName, planName, serviceInstanceName string, params map[string]interface{}) (models.ServicePlanFields, error) {
func (cmd CreateService) CreateService(serviceName, planName, serviceInstanceName string, params map[string]interface{}, tags []string) (models.ServicePlanFields, error) {
offerings, apiErr := cmd.serviceBuilder.GetServicesByNameForSpaceWithPlans(cmd.config.SpaceFields().Guid, serviceName)
if apiErr != nil {
return models.ServicePlanFields{}, apiErr
Expand All @@ -121,7 +126,7 @@ func (cmd CreateService) CreateService(serviceName, planName, serviceInstanceNam
return plan, apiErr
}

apiErr = cmd.serviceRepo.CreateServiceInstance(serviceInstanceName, plan.Guid, params)
apiErr = cmd.serviceRepo.CreateServiceInstance(serviceInstanceName, plan.Guid, params, tags)
return plan, apiErr
}

Expand All @@ -140,6 +145,15 @@ func (cmd CreateService) parseArbitraryParams(paramsFileOrJson string) (map[stri
return paramsMap, nil
}

func (cmd CreateService) parseTags(tags string) []string {
tags = strings.Trim(tags, `"`)
tagsList := strings.Split(tags, ",")
for index, tag := range tagsList {
tagsList[index] = strings.Trim(tag, " ")
}
return tagsList
}

func findPlanFromOfferings(offerings models.ServiceOfferings, name string) (plan models.ServicePlanFields, err error) {
for _, offering := range offerings {
for _, plan := range offering.Plans {
Expand Down
12 changes: 12 additions & 0 deletions cf/commands/service/create_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ var _ = Describe("create-service command", func() {
Expect(serviceRepo.CreateServiceInstanceArgs.PlanGuid).To(Equal("cleardb-spark-guid"))
})

Context("when passing in tags", func() {
It("sucessfully creates a service and passes the tags as json", func() {
callCreateService([]string{"cleardb", "spark", "my-cleardb-service", "-t", "tag1, tag2,tag3, tag4"})

Expect(ui.Outputs).To(ContainSubstrings(
[]string{"Creating service instance", "my-cleardb-service", "my-org", "my-space", "my-user"},
[]string{"OK"},
))
Expect(serviceRepo.CreateServiceInstanceArgs.Tags).To(ConsistOf("tag1", "tag2", "tag3", "tag4"))
})
})

Context("when passing arbitrary params", func() {
Context("as a json string", func() {
It("successfully creates a service and passes the params as a json string", func() {
Expand Down
7 changes: 6 additions & 1 deletion cf/i18n/resources/de_DE.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
"modified": false
},
{
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service cleardb spark clear-db-mine\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"modified": true
},
Expand Down Expand Up @@ -4539,6 +4539,11 @@
"translation": "Use a one-time password to login",
"modified": false
},
{
"id": "User provided tags",
"translation": "User provided tags",
"modified": false
},
{
"id": "User {{.TargetUser}} does not exist.",
"translation": "User {{.TargetUser}} does not exist.",
Expand Down
9 changes: 7 additions & 2 deletions cf/i18n/resources/en_US.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,8 +640,8 @@
"modified": false
},
{
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"modified": false
},
{
Expand Down Expand Up @@ -4539,6 +4539,11 @@
"translation": "Use a one-time password to login",
"modified": false
},
{
"id": "User provided tags",
"translation": "User provided tags",
"modified": false
},
{
"id": "User {{.TargetUser}} does not exist.",
"translation": "User {{.TargetUser}} does not exist.",
Expand Down
7 changes: 6 additions & 1 deletion cf/i18n/resources/es_ES.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
"modified": false
},
{
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service cleardb spark clear-db-mine\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"modified": true
},
Expand Down Expand Up @@ -4539,6 +4539,11 @@
"translation": "Usar un clave por única vez para iniciar sesión",
"modified": false
},
{
"id": "User provided tags",
"translation": "User provided tags",
"modified": false
},
{
"id": "User {{.TargetUser}} does not exist.",
"translation": "El usuario {{.TargetUser}} no existe.",
Expand Down
7 changes: 6 additions & 1 deletion cf/i18n/resources/fr_FR.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
"modified": false
},
{
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service SERVICE PLAN INSTANCE_DE_SERVICE\n\nExemple: CF_NAME create-service cleardb spark clear-db-mine\n\n:CONSEIL:\n Utilisez 'CF_NAME create-user-provided-service' pour rendre disponibles aux applications cf, les services fournis par l'utilisateur",
"modified": true
},
Expand Down Expand Up @@ -4539,6 +4539,11 @@
"translation": "Utilisez un mot de passe unique pour se connecter",
"modified": false
},
{
"id": "User provided tags",
"translation": "User provided tags",
"modified": false
},
{
"id": "User {{.TargetUser}} does not exist.",
"translation": "Utilisateur {{.TargetUser}} n'existe pas.",
Expand Down
7 changes: 6 additions & 1 deletion cf/i18n/resources/it_IT.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
"modified": false
},
{
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service cleardb spark clear-db-mine\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"modified": true
},
Expand Down Expand Up @@ -4539,6 +4539,11 @@
"translation": "Use a one-time password to login",
"modified": false
},
{
"id": "User provided tags",
"translation": "User provided tags",
"modified": false
},
{
"id": "User {{.TargetUser}} does not exist.",
"translation": "User {{.TargetUser}} does not exist.",
Expand Down
7 changes: 6 additions & 1 deletion cf/i18n/resources/ja_JA.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
"modified": false
},
{
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service cleardb spark clear-db-mine\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"modified": true
},
Expand Down Expand Up @@ -4539,6 +4539,11 @@
"translation": "Use a one-time password to login",
"modified": false
},
{
"id": "User provided tags",
"translation": "User provided tags",
"modified": false
},
{
"id": "User {{.TargetUser}} does not exist.",
"translation": "User {{.TargetUser}} does not exist.",
Expand Down
7 changes: 6 additions & 1 deletion cf/i18n/resources/pt_BR.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
"modified": false
},
{
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service SERVIÇO PLANO SERVICE_INSTANCE\n\nEXEMPLO:\n CF_NAME create-service cleardb spark clear-db-mine\n\nDICA:\n Utilize 'CF_NAME create-user-provided-service' para fazer com que serviços fornecidos pelo usuário sejam disponíveis para apps",
"modified": true
},
Expand Down Expand Up @@ -4539,6 +4539,11 @@
"translation": "Utilize uma senha de uso único para conectar",
"modified": false
},
{
"id": "User provided tags",
"translation": "User provided tags",
"modified": false
},
{
"id": "User {{.TargetUser}} does not exist.",
"translation": "Usuário {{.TargetUser}} não existe.",
Expand Down
7 changes: 6 additions & 1 deletion cf/i18n/resources/zh_Hans.all.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
"modified": false
},
{
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"id": "CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-t TAGS]\n\nEXAMPLE:\n CF_NAME create-service dbaas silver mydb\n CF_NAME create-service dbaas silver mydb -t \"list, of, tags\"\n\nTIP:\n Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps",
"translation": "CF_NAME create-service 服务类型 服务计划 实例名称\n\n示例:\n CF_NAME create-service cleardb spark clear-db-mine\n\n小贴士:\n 使用'CF_NAME create-user-provided-service'来创建由用户提供的服务供应用使用。",
"modified": true
},
Expand Down Expand Up @@ -4539,6 +4539,11 @@
"translation": "使用一次性密码登录",
"modified": false
},
{
"id": "User provided tags",
"translation": "User provided tags",
"modified": false
},
{
"id": "User {{.TargetUser}} does not exist.",
"translation": "用户{{.TargetUser}}不存在.",
Expand Down
Loading

0 comments on commit dd5c171

Please sign in to comment.