github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/commands/application/scale.go (about) 1 package application 2 3 import ( 4 "github.com/cloudfoundry/cli/cf/api/applications" 5 "github.com/cloudfoundry/cli/cf/command_registry" 6 "github.com/cloudfoundry/cli/cf/configuration/core_config" 7 "github.com/cloudfoundry/cli/cf/formatters" 8 . "github.com/cloudfoundry/cli/cf/i18n" 9 "github.com/cloudfoundry/cli/cf/models" 10 "github.com/cloudfoundry/cli/cf/requirements" 11 "github.com/cloudfoundry/cli/cf/terminal" 12 "github.com/cloudfoundry/cli/flags" 13 "github.com/cloudfoundry/cli/flags/flag" 14 ) 15 16 type Scale struct { 17 ui terminal.UI 18 config core_config.Reader 19 restarter ApplicationRestarter 20 appReq requirements.ApplicationRequirement 21 appRepo applications.ApplicationRepository 22 } 23 24 func init() { 25 command_registry.Register(&Scale{}) 26 } 27 28 func (cmd *Scale) MetaData() command_registry.CommandMetadata { 29 fs := make(map[string]flags.FlagSet) 30 fs["i"] = &cliFlags.IntFlag{Name: "i", Usage: T("Number of instances")} 31 fs["k"] = &cliFlags.StringFlag{Name: "k", Usage: T("Disk limit (e.g. 256M, 1024M, 1G)")} 32 fs["m"] = &cliFlags.StringFlag{Name: "m", Usage: T("Memory limit (e.g. 256M, 1024M, 1G)")} 33 fs["f"] = &cliFlags.BoolFlag{Name: "f", Usage: T("Force restart of app without prompt")} 34 35 return command_registry.CommandMetadata{ 36 Name: "scale", 37 Description: T("Change or view the instance count, disk space limit, and memory limit for an app"), 38 Usage: T("CF_NAME scale APP_NAME [-i INSTANCES] [-k DISK] [-m MEMORY] [-f]"), 39 Flags: fs, 40 } 41 } 42 43 func (cmd *Scale) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) (reqs []requirements.Requirement, err error) { 44 if len(fc.Args()) != 1 { 45 cmd.ui.Failed(T("Incorrect Usage. Requires an argument\n\n") + command_registry.Commands.CommandUsage("scale")) 46 } 47 48 cmd.appReq = requirementsFactory.NewApplicationRequirement(fc.Args()[0]) 49 50 reqs = []requirements.Requirement{ 51 requirementsFactory.NewLoginRequirement(), 52 requirementsFactory.NewTargetedSpaceRequirement(), 53 cmd.appReq, 54 } 55 return 56 } 57 58 func (cmd *Scale) SetDependency(deps command_registry.Dependency, pluginCall bool) command_registry.Command { 59 cmd.ui = deps.Ui 60 cmd.config = deps.Config 61 cmd.appRepo = deps.RepoLocator.GetApplicationRepository() 62 63 //get command from registry for dependency 64 commandDep := command_registry.Commands.FindCommand("restart") 65 commandDep = commandDep.SetDependency(deps, false) 66 cmd.restarter = commandDep.(ApplicationRestarter) 67 68 return cmd 69 } 70 71 var bytesInAMegabyte int64 = 1024 * 1024 72 73 func (cmd *Scale) Execute(c flags.FlagContext) { 74 currentApp := cmd.appReq.GetApplication() 75 if !anyFlagsSet(c) { 76 cmd.ui.Say(T("Showing current scale of app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...", 77 map[string]interface{}{ 78 "AppName": terminal.EntityNameColor(currentApp.Name), 79 "OrgName": terminal.EntityNameColor(cmd.config.OrganizationFields().Name), 80 "SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name), 81 "CurrentUser": terminal.EntityNameColor(cmd.config.Username()), 82 })) 83 cmd.ui.Ok() 84 cmd.ui.Say("") 85 86 cmd.ui.Say("%s %s", terminal.HeaderColor(T("memory:")), formatters.ByteSize(currentApp.Memory*bytesInAMegabyte)) 87 cmd.ui.Say("%s %s", terminal.HeaderColor(T("disk:")), formatters.ByteSize(currentApp.DiskQuota*bytesInAMegabyte)) 88 cmd.ui.Say("%s %d", terminal.HeaderColor(T("instances:")), currentApp.InstanceCount) 89 90 return 91 } 92 93 params := models.AppParams{} 94 shouldRestart := false 95 96 if c.String("m") != "" { 97 memory, err := formatters.ToMegabytes(c.String("m")) 98 if err != nil { 99 cmd.ui.Failed(T("Invalid memory limit: {{.Memory}}\n{{.ErrorDescription}}", 100 map[string]interface{}{ 101 "Memory": c.String("m"), 102 "ErrorDescription": err, 103 })) 104 } 105 params.Memory = &memory 106 shouldRestart = true 107 } 108 109 if c.String("k") != "" { 110 diskQuota, err := formatters.ToMegabytes(c.String("k")) 111 if err != nil { 112 cmd.ui.Failed(T("Invalid disk quota: {{.DiskQuota}}\n{{.ErrorDescription}}", 113 map[string]interface{}{ 114 "DiskQuota": c.String("k"), 115 "ErrorDescription": err, 116 })) 117 } 118 params.DiskQuota = &diskQuota 119 shouldRestart = true 120 } 121 122 if c.IsSet("i") { 123 instances := c.Int("i") 124 params.InstanceCount = &instances 125 } 126 127 if shouldRestart && !cmd.confirmRestart(c, currentApp.Name) { 128 return 129 } 130 131 cmd.ui.Say(T("Scaling app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...", 132 map[string]interface{}{ 133 "AppName": terminal.EntityNameColor(currentApp.Name), 134 "OrgName": terminal.EntityNameColor(cmd.config.OrganizationFields().Name), 135 "SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name), 136 "CurrentUser": terminal.EntityNameColor(cmd.config.Username()), 137 })) 138 139 updatedApp, apiErr := cmd.appRepo.Update(currentApp.Guid, params) 140 if apiErr != nil { 141 cmd.ui.Failed(apiErr.Error()) 142 return 143 } 144 145 cmd.ui.Ok() 146 147 if shouldRestart { 148 cmd.restarter.ApplicationRestart(updatedApp, cmd.config.OrganizationFields().Name, cmd.config.SpaceFields().Name) 149 } 150 } 151 152 func (cmd *Scale) confirmRestart(context flags.FlagContext, appName string) bool { 153 if context.Bool("f") { 154 return true 155 } else { 156 result := cmd.ui.Confirm(T("This will cause the app to restart. Are you sure you want to scale {{.AppName}}?", 157 map[string]interface{}{"AppName": terminal.EntityNameColor(appName)})) 158 cmd.ui.Say("") 159 return result 160 } 161 } 162 163 func anyFlagsSet(context flags.FlagContext) bool { 164 return context.IsSet("m") || context.IsSet("k") || context.IsSet("i") 165 }