github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/commands/application/app.go (about)

     1  package application
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	. "github.com/cloudfoundry/cli/cf/i18n"
     8  	"github.com/cloudfoundry/cli/flags"
     9  	"github.com/cloudfoundry/cli/flags/flag"
    10  	"github.com/cloudfoundry/cli/plugin/models"
    11  
    12  	"github.com/cloudfoundry/cli/cf/api"
    13  	"github.com/cloudfoundry/cli/cf/api/app_instances"
    14  	"github.com/cloudfoundry/cli/cf/command_registry"
    15  	"github.com/cloudfoundry/cli/cf/configuration/core_config"
    16  	"github.com/cloudfoundry/cli/cf/errors"
    17  	"github.com/cloudfoundry/cli/cf/formatters"
    18  	"github.com/cloudfoundry/cli/cf/models"
    19  	"github.com/cloudfoundry/cli/cf/requirements"
    20  	"github.com/cloudfoundry/cli/cf/terminal"
    21  	"github.com/cloudfoundry/cli/cf/ui_helpers"
    22  )
    23  
    24  type ApplicationDisplayer interface {
    25  	ShowApp(app models.Application, orgName string, spaceName string)
    26  }
    27  
    28  type ShowApp struct {
    29  	ui               terminal.UI
    30  	config           core_config.Reader
    31  	appSummaryRepo   api.AppSummaryRepository
    32  	appInstancesRepo app_instances.AppInstancesRepository
    33  	appReq           requirements.ApplicationRequirement
    34  	pluginAppModel   *plugin_models.GetAppModel
    35  	pluginCall       bool
    36  }
    37  
    38  func init() {
    39  	command_registry.Register(&ShowApp{})
    40  }
    41  
    42  func (cmd *ShowApp) MetaData() command_registry.CommandMetadata {
    43  	fs := make(map[string]flags.FlagSet)
    44  	fs["guid"] = &cliFlags.BoolFlag{Name: "guid", Usage: T("Retrieve and display the given app's guid.  All other health and status output for the app is suppressed.")}
    45  
    46  	return command_registry.CommandMetadata{
    47  		Name:        "app",
    48  		Description: T("Display health and status for app"),
    49  		Usage:       T("CF_NAME app APP_NAME"),
    50  		Flags:       fs,
    51  	}
    52  }
    53  
    54  func (cmd *ShowApp) Requirements(requirementsFactory requirements.Factory, fc flags.FlagContext) (reqs []requirements.Requirement, err error) {
    55  	if len(fc.Args()) != 1 {
    56  		cmd.ui.Failed(T("Incorrect Usage. Requires an argument\n\n") + command_registry.Commands.CommandUsage("app"))
    57  	}
    58  
    59  	cmd.appReq = requirementsFactory.NewApplicationRequirement(fc.Args()[0])
    60  
    61  	reqs = []requirements.Requirement{
    62  		requirementsFactory.NewLoginRequirement(),
    63  		requirementsFactory.NewTargetedSpaceRequirement(),
    64  		cmd.appReq,
    65  	}
    66  	return
    67  }
    68  
    69  func (cmd *ShowApp) SetDependency(deps command_registry.Dependency, pluginCall bool) command_registry.Command {
    70  	cmd.ui = deps.Ui
    71  	cmd.config = deps.Config
    72  	cmd.appSummaryRepo = deps.RepoLocator.GetAppSummaryRepository()
    73  	cmd.appInstancesRepo = deps.RepoLocator.GetAppInstancesRepository()
    74  
    75  	cmd.pluginAppModel = deps.PluginModels.Application
    76  	cmd.pluginCall = pluginCall
    77  
    78  	return cmd
    79  }
    80  
    81  func (cmd *ShowApp) Execute(c flags.FlagContext) {
    82  	app := cmd.appReq.GetApplication()
    83  
    84  	if cmd.pluginCall {
    85  		cmd.populatePluginModel(app)
    86  	}
    87  
    88  	if c.Bool("guid") {
    89  		cmd.ui.Say(app.Guid)
    90  	} else {
    91  		cmd.ShowApp(app, cmd.config.OrganizationFields().Name, cmd.config.SpaceFields().Name)
    92  	}
    93  }
    94  
    95  func (cmd *ShowApp) ShowApp(app models.Application, orgName, spaceName string) {
    96  	cmd.ui.Say(T("Showing health and status for app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...",
    97  		map[string]interface{}{
    98  			"AppName":   terminal.EntityNameColor(app.Name),
    99  			"OrgName":   terminal.EntityNameColor(orgName),
   100  			"SpaceName": terminal.EntityNameColor(spaceName),
   101  			"Username":  terminal.EntityNameColor(cmd.config.Username())}))
   102  
   103  	application, apiErr := cmd.appSummaryRepo.GetSummary(app.Guid)
   104  
   105  	appIsStopped := (application.State == "stopped")
   106  	if err, ok := apiErr.(errors.HttpError); ok {
   107  		if err.ErrorCode() == errors.APP_STOPPED || err.ErrorCode() == errors.APP_NOT_STAGED {
   108  			appIsStopped = true
   109  		}
   110  	}
   111  
   112  	if apiErr != nil && !appIsStopped {
   113  		cmd.ui.Failed(apiErr.Error())
   114  		return
   115  	}
   116  
   117  	var instances []models.AppInstanceFields
   118  	instances, apiErr = cmd.appInstancesRepo.GetInstances(app.Guid)
   119  	if apiErr != nil && !appIsStopped {
   120  		cmd.ui.Failed(apiErr.Error())
   121  		return
   122  	}
   123  
   124  	if apiErr != nil && !appIsStopped {
   125  		cmd.ui.Failed(apiErr.Error())
   126  		return
   127  	}
   128  
   129  	cmd.ui.Ok()
   130  	cmd.ui.Say("\n%s %s", terminal.HeaderColor(T("requested state:")), ui_helpers.ColoredAppState(application.ApplicationFields))
   131  	cmd.ui.Say("%s %s", terminal.HeaderColor(T("instances:")), ui_helpers.ColoredAppInstances(application.ApplicationFields))
   132  	cmd.ui.Say(T("{{.Usage}} {{.FormattedMemory}} x {{.InstanceCount}} instances",
   133  		map[string]interface{}{
   134  			"Usage":           terminal.HeaderColor(T("usage:")),
   135  			"FormattedMemory": formatters.ByteSize(application.Memory * formatters.MEGABYTE),
   136  			"InstanceCount":   application.InstanceCount}))
   137  
   138  	var urls []string
   139  	for _, route := range application.Routes {
   140  		urls = append(urls, route.URL())
   141  	}
   142  
   143  	cmd.ui.Say("%s %s", terminal.HeaderColor(T("urls:")), strings.Join(urls, ", "))
   144  	var lastUpdated string
   145  	if application.PackageUpdatedAt != nil {
   146  		lastUpdated = application.PackageUpdatedAt.Format("Mon Jan 2 15:04:05 MST 2006")
   147  	} else {
   148  		lastUpdated = "unknown"
   149  	}
   150  	cmd.ui.Say("%s %s", terminal.HeaderColor(T("last uploaded:")), lastUpdated)
   151  	if app.Stack != nil {
   152  		cmd.ui.Say("%s %s", terminal.HeaderColor(T("stack:")), app.Stack.Name)
   153  	} else {
   154  		cmd.ui.Say("%s %s", terminal.HeaderColor(T("stack:")), "unknown")
   155  	}
   156  
   157  	if app.Buildpack != "" {
   158  		cmd.ui.Say("%s %s\n", terminal.HeaderColor(T("buildpack:")), app.Buildpack)
   159  	} else if app.DetectedBuildpack != "" {
   160  		cmd.ui.Say("%s %s\n", terminal.HeaderColor(T("buildpack:")), app.DetectedBuildpack)
   161  	} else {
   162  		cmd.ui.Say("%s %s\n", terminal.HeaderColor(T("buildpack:")), "unknown")
   163  	}
   164  
   165  	if appIsStopped {
   166  		cmd.ui.Say(T("There are no running instances of this app."))
   167  		return
   168  	}
   169  
   170  	table := terminal.NewTable(cmd.ui, []string{"", T("state"), T("since"), T("cpu"), T("memory"), T("disk"), T("details")})
   171  
   172  	for index, instance := range instances {
   173  		table.Add(
   174  			fmt.Sprintf("#%d", index),
   175  			ui_helpers.ColoredInstanceState(instance),
   176  			instance.Since.Format("2006-01-02 03:04:05 PM"),
   177  			fmt.Sprintf("%.1f%%", instance.CpuUsage*100),
   178  			fmt.Sprintf(T("{{.MemUsage}} of {{.MemQuota}}",
   179  				map[string]interface{}{
   180  					"MemUsage": formatters.ByteSize(instance.MemUsage),
   181  					"MemQuota": formatters.ByteSize(instance.MemQuota)})),
   182  			fmt.Sprintf(T("{{.DiskUsage}} of {{.DiskQuota}}",
   183  				map[string]interface{}{
   184  					"DiskUsage": formatters.ByteSize(instance.DiskUsage),
   185  					"DiskQuota": formatters.ByteSize(instance.DiskQuota)})),
   186  			fmt.Sprintf("%s", instance.Details),
   187  		)
   188  
   189  		if cmd.pluginCall {
   190  			i := plugin_models.GetApp_AppInstanceFields{}
   191  			i.State = fmt.Sprintf("%s", instance.State)
   192  			i.Details = instance.Details
   193  			i.Since = instance.Since
   194  			i.CpuUsage = instance.CpuUsage
   195  			i.DiskQuota = instance.DiskQuota
   196  			i.DiskUsage = instance.DiskUsage
   197  			i.MemQuota = instance.MemQuota
   198  			i.MemUsage = instance.MemUsage
   199  			cmd.pluginAppModel.Instances = append(cmd.pluginAppModel.Instances, i)
   200  		}
   201  	}
   202  
   203  	table.Print()
   204  }
   205  
   206  func (cmd *ShowApp) populatePluginModel(app models.Application) {
   207  	cmd.pluginAppModel.Name = app.Name
   208  	cmd.pluginAppModel.State = app.State
   209  	cmd.pluginAppModel.Guid = app.Guid
   210  	cmd.pluginAppModel.BuildpackUrl = app.BuildpackUrl
   211  	cmd.pluginAppModel.Command = app.Command
   212  	cmd.pluginAppModel.Diego = app.Diego
   213  	cmd.pluginAppModel.DetectedStartCommand = app.DetectedStartCommand
   214  	cmd.pluginAppModel.DiskQuota = app.DiskQuota
   215  	cmd.pluginAppModel.EnvironmentVars = app.EnvironmentVars
   216  	cmd.pluginAppModel.InstanceCount = app.InstanceCount
   217  	cmd.pluginAppModel.Memory = app.Memory
   218  	cmd.pluginAppModel.RunningInstances = app.RunningInstances
   219  	cmd.pluginAppModel.HealthCheckTimeout = app.HealthCheckTimeout
   220  	cmd.pluginAppModel.SpaceGuid = app.SpaceGuid
   221  	cmd.pluginAppModel.PackageUpdatedAt = app.PackageUpdatedAt
   222  	cmd.pluginAppModel.PackageState = app.PackageState
   223  	cmd.pluginAppModel.StagingFailedReason = app.StagingFailedReason
   224  
   225  	cmd.pluginAppModel.Stack = &plugin_models.GetApp_Stack{
   226  		Name: app.Stack.Name,
   227  		Guid: app.Stack.Guid,
   228  	}
   229  
   230  	for i, _ := range app.Routes {
   231  		cmd.pluginAppModel.Routes = append(cmd.pluginAppModel.Routes, plugin_models.GetApp_RouteSummary{
   232  			Host: app.Routes[i].Host,
   233  			Guid: app.Routes[i].Guid,
   234  			Domain: plugin_models.GetApp_DomainFields{
   235  				Name:                   app.Routes[i].Domain.Name,
   236  				Guid:                   app.Routes[i].Domain.Guid,
   237  				Shared:                 app.Routes[i].Domain.Shared,
   238  				OwningOrganizationGuid: app.Routes[i].Domain.OwningOrganizationGuid,
   239  			},
   240  		})
   241  	}
   242  
   243  	for i, _ := range app.Services {
   244  		cmd.pluginAppModel.Services = append(cmd.pluginAppModel.Services, plugin_models.GetApp_ServiceSummary{
   245  			Name: app.Services[i].Name,
   246  			Guid: app.Services[i].Guid,
   247  		})
   248  	}
   249  }