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  }