github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+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_metadata"
     6  	"github.com/cloudfoundry/cli/cf/configuration/core_config"
     7  	"github.com/cloudfoundry/cli/cf/flag_helpers"
     8  	"github.com/cloudfoundry/cli/cf/formatters"
     9  	. "github.com/cloudfoundry/cli/cf/i18n"
    10  	"github.com/cloudfoundry/cli/cf/models"
    11  	"github.com/cloudfoundry/cli/cf/requirements"
    12  	"github.com/cloudfoundry/cli/cf/terminal"
    13  	"github.com/codegangsta/cli"
    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 NewScale(ui terminal.UI, config core_config.Reader, restarter ApplicationRestarter, appRepo applications.ApplicationRepository) (cmd *Scale) {
    25  	cmd = new(Scale)
    26  	cmd.ui = ui
    27  	cmd.config = config
    28  	cmd.restarter = restarter
    29  	cmd.appRepo = appRepo
    30  	return
    31  }
    32  
    33  func (cmd *Scale) Metadata() command_metadata.CommandMetadata {
    34  	return command_metadata.CommandMetadata{
    35  		Name:        "scale",
    36  		Description: T("Change or view the instance count, disk space limit, and memory limit for an app"),
    37  		Usage:       T("CF_NAME scale APP_NAME [-i INSTANCES] [-k DISK] [-m MEMORY] [-f]"),
    38  		Flags: []cli.Flag{
    39  			flag_helpers.NewIntFlag("i", T("Number of instances")),
    40  			flag_helpers.NewStringFlag("k", T("Disk limit (e.g. 256M, 1024M, 1G)")),
    41  			flag_helpers.NewStringFlag("m", T("Memory limit (e.g. 256M, 1024M, 1G)")),
    42  			cli.BoolFlag{Name: "f", Usage: T("Force restart of app without prompt")},
    43  		},
    44  	}
    45  }
    46  
    47  func (cmd *Scale) GetRequirements(requirementsFactory requirements.Factory, c *cli.Context) (reqs []requirements.Requirement, err error) {
    48  	if len(c.Args()) != 1 {
    49  		cmd.ui.FailWithUsage(c)
    50  	}
    51  
    52  	cmd.appReq = requirementsFactory.NewApplicationRequirement(c.Args()[0])
    53  
    54  	reqs = []requirements.Requirement{
    55  		requirementsFactory.NewLoginRequirement(),
    56  		requirementsFactory.NewTargetedSpaceRequirement(),
    57  		cmd.appReq,
    58  	}
    59  	return
    60  }
    61  
    62  var bytesInAMegabyte int64 = 1024 * 1024
    63  
    64  func (cmd *Scale) Run(c *cli.Context) {
    65  	currentApp := cmd.appReq.GetApplication()
    66  	if !anyFlagsSet(c) {
    67  		cmd.ui.Say(T("Showing current scale of app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...",
    68  			map[string]interface{}{
    69  				"AppName":     terminal.EntityNameColor(currentApp.Name),
    70  				"OrgName":     terminal.EntityNameColor(cmd.config.OrganizationFields().Name),
    71  				"SpaceName":   terminal.EntityNameColor(cmd.config.SpaceFields().Name),
    72  				"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
    73  			}))
    74  		cmd.ui.Ok()
    75  		cmd.ui.Say("")
    76  
    77  		cmd.ui.Say("%s %s", terminal.HeaderColor(T("memory:")), formatters.ByteSize(currentApp.Memory*bytesInAMegabyte))
    78  		cmd.ui.Say("%s %s", terminal.HeaderColor(T("disk:")), formatters.ByteSize(currentApp.DiskQuota*bytesInAMegabyte))
    79  		cmd.ui.Say("%s %d", terminal.HeaderColor(T("instances:")), currentApp.InstanceCount)
    80  
    81  		return
    82  	}
    83  
    84  	params := models.AppParams{}
    85  	shouldRestart := false
    86  
    87  	if c.String("m") != "" {
    88  		memory, err := formatters.ToMegabytes(c.String("m"))
    89  		if err != nil {
    90  			cmd.ui.Failed(T("Invalid memory limit: {{.Memory}}\n{{.ErrorDescription}}",
    91  				map[string]interface{}{
    92  					"Memory":           c.String("m"),
    93  					"ErrorDescription": err,
    94  				}))
    95  		}
    96  		params.Memory = &memory
    97  		shouldRestart = true
    98  	}
    99  
   100  	if c.String("k") != "" {
   101  		diskQuota, err := formatters.ToMegabytes(c.String("k"))
   102  		if err != nil {
   103  			cmd.ui.Failed(T("Invalid disk quota: {{.DiskQuota}}\n{{.ErrorDescription}}",
   104  				map[string]interface{}{
   105  					"DiskQuota":        c.String("k"),
   106  					"ErrorDescription": err,
   107  				}))
   108  		}
   109  		params.DiskQuota = &diskQuota
   110  		shouldRestart = true
   111  	}
   112  
   113  	if c.IsSet("i") {
   114  		instances := c.Int("i")
   115  		if instances > 0 {
   116  			params.InstanceCount = &instances
   117  		} else {
   118  			cmd.ui.Failed(T("Invalid instance count: {{.InstanceCount}}\nInstance count must be a positive integer",
   119  				map[string]interface{}{
   120  					"InstanceCount": instances,
   121  				}))
   122  		}
   123  	}
   124  
   125  	if shouldRestart && !cmd.confirmRestart(c, currentApp.Name) {
   126  		return
   127  	}
   128  
   129  	cmd.ui.Say(T("Scaling app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.CurrentUser}}...",
   130  		map[string]interface{}{
   131  			"AppName":     terminal.EntityNameColor(currentApp.Name),
   132  			"OrgName":     terminal.EntityNameColor(cmd.config.OrganizationFields().Name),
   133  			"SpaceName":   terminal.EntityNameColor(cmd.config.SpaceFields().Name),
   134  			"CurrentUser": terminal.EntityNameColor(cmd.config.Username()),
   135  		}))
   136  
   137  	updatedApp, apiErr := cmd.appRepo.Update(currentApp.Guid, params)
   138  	if apiErr != nil {
   139  		cmd.ui.Failed(apiErr.Error())
   140  		return
   141  	}
   142  
   143  	cmd.ui.Ok()
   144  
   145  	if shouldRestart {
   146  		cmd.restarter.ApplicationRestart(updatedApp, cmd.config.OrganizationFields().Name, cmd.config.SpaceFields().Name)
   147  	}
   148  }
   149  
   150  func (cmd *Scale) confirmRestart(context *cli.Context, appName string) bool {
   151  	if context.Bool("f") {
   152  		return true
   153  	} else {
   154  		result := cmd.ui.Confirm(T("This will cause the app to restart. Are you sure you want to scale {{.AppName}}?",
   155  			map[string]interface{}{"AppName": terminal.EntityNameColor(appName)}))
   156  		cmd.ui.Say("")
   157  		return result
   158  	}
   159  }
   160  
   161  func anyFlagsSet(context *cli.Context) bool {
   162  	return context.IsSet("m") || context.IsSet("k") || context.IsSet("i")
   163  }