github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/cf/commands/application/app.go (about)

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