github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+incompatible/cf/commands/service/update_user_provided_service.go (about) 1 package service 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "strings" 8 9 "code.cloudfoundry.org/cli/cf/flagcontext" 10 "code.cloudfoundry.org/cli/cf/flags" 11 . "code.cloudfoundry.org/cli/cf/i18n" 12 13 "code.cloudfoundry.org/cli/cf" 14 "code.cloudfoundry.org/cli/cf/api" 15 "code.cloudfoundry.org/cli/cf/commandregistry" 16 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 17 "code.cloudfoundry.org/cli/cf/requirements" 18 "code.cloudfoundry.org/cli/cf/terminal" 19 ) 20 21 type UpdateUserProvidedService struct { 22 ui terminal.UI 23 config coreconfig.Reader 24 userProvidedServiceInstanceRepo api.UserProvidedServiceInstanceRepository 25 serviceInstanceReq requirements.ServiceInstanceRequirement 26 } 27 28 func init() { 29 commandregistry.Register(&UpdateUserProvidedService{}) 30 } 31 32 func (cmd *UpdateUserProvidedService) MetaData() commandregistry.CommandMetadata { 33 fs := make(map[string]flags.FlagSet) 34 fs["p"] = &flags.StringFlag{ShortName: "p", Usage: T("Credentials, provided inline or in a file, to be exposed in the VCAP_SERVICES environment variable for bound applications")} 35 fs["l"] = &flags.StringFlag{ShortName: "l", Usage: T("URL to which logs for bound applications will be streamed")} 36 fs["r"] = &flags.StringFlag{ShortName: "r", Usage: T("URL to which requests for bound routes will be forwarded. Scheme for this URL must be https")} 37 38 return commandregistry.CommandMetadata{ 39 Name: "update-user-provided-service", 40 ShortName: "uups", 41 Description: T("Update user-provided service instance"), 42 Usage: []string{ 43 T(`CF_NAME update-user-provided-service SERVICE_INSTANCE [-p CREDENTIALS] [-l SYSLOG_DRAIN_URL] [-r ROUTE_SERVICE_URL] 44 45 Pass comma separated credential parameter names to enable interactive mode: 46 CF_NAME update-user-provided-service SERVICE_INSTANCE -p "comma, separated, parameter, names" 47 48 Pass credential parameters as JSON to create a service non-interactively: 49 CF_NAME update-user-provided-service SERVICE_INSTANCE -p '{"key1":"value1","key2":"value2"}' 50 51 Specify a path to a file containing JSON: 52 CF_NAME update-user-provided-service SERVICE_INSTANCE -p PATH_TO_FILE`), 53 }, 54 Examples: []string{ 55 `CF_NAME update-user-provided-service my-db-mine -p '{"username":"admin", "password":"pa55woRD"}'`, 56 "CF_NAME update-user-provided-service my-db-mine -p /path/to/credentials.json", 57 "CF_NAME update-user-provided-service my-drain-service -l syslog://example.com", 58 "CF_NAME update-user-provided-service my-route-service -r https://example.com", 59 }, 60 Flags: fs, 61 } 62 } 63 64 func (cmd *UpdateUserProvidedService) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) ([]requirements.Requirement, error) { 65 if len(fc.Args()) != 1 { 66 cmd.ui.Failed(T("Incorrect Usage. Requires an argument\n\n") + commandregistry.Commands.CommandUsage("update-user-provided-service")) 67 return nil, fmt.Errorf("Incorrect usage: %d arguments of %d required", len(fc.Args()), 1) 68 } 69 70 cmd.serviceInstanceReq = requirementsFactory.NewServiceInstanceRequirement(fc.Args()[0]) 71 72 reqs := []requirements.Requirement{ 73 requirementsFactory.NewLoginRequirement(), 74 cmd.serviceInstanceReq, 75 } 76 77 if fc.IsSet("r") { 78 reqs = append(reqs, requirementsFactory.NewMinAPIVersionRequirement("Option '-r'", cf.MultipleAppPortsMinimumAPIVersion)) 79 } 80 81 return reqs, nil 82 } 83 84 func (cmd *UpdateUserProvidedService) SetDependency(deps commandregistry.Dependency, pluginCall bool) commandregistry.Command { 85 cmd.ui = deps.UI 86 cmd.config = deps.Config 87 cmd.userProvidedServiceInstanceRepo = deps.RepoLocator.GetUserProvidedServiceInstanceRepository() 88 return cmd 89 } 90 91 func (cmd *UpdateUserProvidedService) Execute(c flags.FlagContext) error { 92 serviceInstance := cmd.serviceInstanceReq.GetServiceInstance() 93 if !serviceInstance.IsUserProvided() { 94 return errors.New(T("Service Instance is not user provided")) 95 } 96 97 drainURL := c.String("l") 98 credentials := strings.Trim(c.String("p"), `'"`) 99 routeServiceURL := c.String("r") 100 101 credentialsMap := make(map[string]interface{}) 102 103 if c.IsSet("p") { 104 jsonBytes, err := flagcontext.GetContentsFromFlagValue(credentials) 105 if err != nil { 106 return err 107 } 108 109 err = json.Unmarshal(jsonBytes, &credentialsMap) 110 if err != nil { 111 for _, param := range strings.Split(credentials, ",") { 112 param = strings.Trim(param, " ") 113 credentialsMap[param] = cmd.ui.Ask(param) 114 } 115 } 116 } 117 118 cmd.ui.Say(T("Updating user provided service {{.ServiceName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...", 119 map[string]interface{}{ 120 "ServiceName": terminal.EntityNameColor(serviceInstance.Name), 121 "OrgName": terminal.EntityNameColor(cmd.config.OrganizationFields().Name), 122 "SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name), 123 "CurrentUser": terminal.EntityNameColor(cmd.config.Username()), 124 })) 125 126 serviceInstance.Params = credentialsMap 127 serviceInstance.SysLogDrainURL = drainURL 128 serviceInstance.RouteServiceURL = routeServiceURL 129 130 err := cmd.userProvidedServiceInstanceRepo.Update(serviceInstance.ServiceInstanceFields) 131 if err != nil { 132 return err 133 } 134 135 cmd.ui.Ok() 136 cmd.ui.Say(T("TIP: Use '{{.CFRestageCommand}}' for any bound apps to ensure your env variable changes take effect", 137 map[string]interface{}{ 138 "CFRestageCommand": terminal.CommandColor(cf.Name + " restage"), 139 })) 140 141 if routeServiceURL == "" && credentials == "" && drainURL == "" { 142 cmd.ui.Warn(T("No flags specified. No changes were made.")) 143 } 144 return nil 145 }