github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/commands/service/create_service.go (about) 1 package service 2 3 import ( 4 "strings" 5 6 "github.com/cloudfoundry/cli/cf/actors/service_builder" 7 "github.com/cloudfoundry/cli/cf/api" 8 "github.com/cloudfoundry/cli/cf/command_registry" 9 "github.com/cloudfoundry/cli/cf/configuration/core_config" 10 "github.com/cloudfoundry/cli/cf/errors" 11 . "github.com/cloudfoundry/cli/cf/i18n" 12 "github.com/cloudfoundry/cli/cf/models" 13 "github.com/cloudfoundry/cli/cf/requirements" 14 "github.com/cloudfoundry/cli/cf/terminal" 15 "github.com/cloudfoundry/cli/cf/ui_helpers" 16 "github.com/cloudfoundry/cli/flags" 17 "github.com/cloudfoundry/cli/flags/flag" 18 "github.com/cloudfoundry/cli/json" 19 ) 20 21 type CreateService struct { 22 ui terminal.UI 23 config core_config.Reader 24 serviceRepo api.ServiceRepository 25 serviceBuilder service_builder.ServiceBuilder 26 } 27 28 func init() { 29 command_registry.Register(&CreateService{}) 30 } 31 32 func (cmd *CreateService) MetaData() command_registry.CommandMetadata { 33 fs := make(map[string]flags.FlagSet) 34 fs["c"] = &cliFlags.StringFlag{Name: "c", Usage: 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.")} 35 fs["t"] = &cliFlags.StringFlag{Name: "t", Usage: T("User provided tags")} 36 37 baseUsage := T("CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE [-c PARAMETERS_AS_JSON] [-t TAGS]") 38 paramsUsage := T(` Optionally provide service-specific configuration parameters in a valid JSON object in-line: 39 40 CF_NAME create-service SERVICE PLAN SERVICE_INSTANCE -c '{"name":"value","name":"value"}' 41 42 Optionally provide a file containing service-specific configuration parameters in a valid JSON object. 43 The path to the parameters file can be an absolute or relative path to a file: 44 45 CF_NAME create-service SERVICE_INSTANCE -c PATH_TO_FILE 46 47 Example of valid JSON object: 48 { 49 "cluster_nodes": { 50 "count": 5, 51 "memory_mb": 1024 52 } 53 }`) 54 exampleUsage := T(`EXAMPLE: 55 Linux/Mac: 56 CF_NAME create-service db-service silver -c '{"ram_gb":4}' 57 58 Windows Command Line: 59 CF_NAME create-service db-service silver -c "{\"ram_gb\":4}" 60 61 Windows PowerShell: 62 CF_NAME create-service db-service silver -c '{\"ram_gb\":4}' 63 64 CF_NAME create-service db-service silver mydb -c ~/workspace/tmp/instance_config.json 65 66 CF_NAME create-service dbaas silver mydb -t "list, of, tags"`) 67 tipsUsage := T(`TIP: 68 Use 'CF_NAME create-user-provided-service' to make user-provided services available to cf apps`) 69 return command_registry.CommandMetadata{ 70 Name: "create-service", 71 ShortName: "cs", 72 Description: T("Create a service instance"), 73 Usage: strings.Join([]string{baseUsage, paramsUsage, exampleUsage, tipsUsage}, "\n\n"), 74 Flags: fs, 75 } 76 } 77 78 func (cmd *CreateService) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) (reqs []requirements.Requirement, err error) { 79 if len(fc.Args()) != 3 { 80 cmd.ui.Failed(T("Incorrect Usage. Requires service, service plan, service instance as arguments\n\n") + command_registry.Commands.CommandUsage("create-service")) 81 } 82 83 reqs = []requirements.Requirement{ 84 requirementsFactory.NewLoginRequirement(), 85 requirementsFactory.NewTargetedSpaceRequirement(), 86 } 87 88 return 89 } 90 91 func (cmd *CreateService) SetDependency(deps command_registry.Dependency, pluginCall bool) command_registry.Command { 92 cmd.ui = deps.Ui 93 cmd.config = deps.Config 94 cmd.serviceRepo = deps.RepoLocator.GetServiceRepository() 95 cmd.serviceBuilder = deps.ServiceBuilder 96 return cmd 97 } 98 99 func (cmd *CreateService) Execute(c flags.FlagContext) { 100 serviceName := c.Args()[0] 101 planName := c.Args()[1] 102 serviceInstanceName := c.Args()[2] 103 params := c.String("c") 104 tags := c.String("t") 105 106 tagsList := ui_helpers.ParseTags(tags) 107 108 paramsMap, err := json.ParseJsonFromFileOrString(params) 109 if err != nil { 110 cmd.ui.Failed(T("Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object.")) 111 } 112 113 cmd.ui.Say(T("Creating service instance {{.ServiceName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...", 114 map[string]interface{}{ 115 "ServiceName": terminal.EntityNameColor(serviceInstanceName), 116 "OrgName": terminal.EntityNameColor(cmd.config.OrganizationFields().Name), 117 "SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name), 118 "CurrentUser": terminal.EntityNameColor(cmd.config.Username()), 119 })) 120 121 plan, err := cmd.CreateService(serviceName, planName, serviceInstanceName, paramsMap, tagsList) 122 123 switch err.(type) { 124 case nil: 125 err := printSuccessMessageForServiceInstance(serviceInstanceName, cmd.serviceRepo, cmd.ui) 126 if err != nil { 127 cmd.ui.Failed(err.Error()) 128 } 129 130 if !plan.Free { 131 cmd.ui.Say("") 132 cmd.ui.Say(T("Attention: The plan `{{.PlanName}}` of service `{{.ServiceName}}` is not free. The instance `{{.ServiceInstanceName}}` will incur a cost. Contact your administrator if you think this is in error.", 133 map[string]interface{}{ 134 "PlanName": terminal.EntityNameColor(plan.Name), 135 "ServiceName": terminal.EntityNameColor(serviceName), 136 "ServiceInstanceName": terminal.EntityNameColor(serviceInstanceName), 137 })) 138 cmd.ui.Say("") 139 } 140 case *errors.ModelAlreadyExistsError: 141 cmd.ui.Ok() 142 cmd.ui.Warn(err.Error()) 143 default: 144 cmd.ui.Failed(err.Error()) 145 } 146 } 147 148 func (cmd CreateService) CreateService(serviceName, planName, serviceInstanceName string, params map[string]interface{}, tags []string) (models.ServicePlanFields, error) { 149 offerings, apiErr := cmd.serviceBuilder.GetServicesByNameForSpaceWithPlans(cmd.config.SpaceFields().Guid, serviceName) 150 if apiErr != nil { 151 return models.ServicePlanFields{}, apiErr 152 } 153 154 plan, apiErr := findPlanFromOfferings(offerings, planName) 155 if apiErr != nil { 156 return plan, apiErr 157 } 158 159 apiErr = cmd.serviceRepo.CreateServiceInstance(serviceInstanceName, plan.Guid, params, tags) 160 return plan, apiErr 161 } 162 163 func findPlanFromOfferings(offerings models.ServiceOfferings, name string) (plan models.ServicePlanFields, err error) { 164 for _, offering := range offerings { 165 for _, plan := range offering.Plans { 166 if name == plan.Name { 167 return plan, nil 168 } 169 } 170 } 171 172 err = errors.New(T("Could not find plan with name {{.ServicePlanName}}", 173 map[string]interface{}{"ServicePlanName": name}, 174 )) 175 return 176 }