github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/cf/commands/application/scale.go (about)

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