github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v6/shared/app_summary_displayer_refactored.go (about)

     1  package shared
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	"code.cloudfoundry.org/bytefmt"
     9  	"code.cloudfoundry.org/cli/actor/v2v3action"
    10  	"code.cloudfoundry.org/cli/actor/v3action"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    12  	"code.cloudfoundry.org/cli/command"
    13  )
    14  
    15  type AppSummaryDisplayer2 struct {
    16  	UI command.UI
    17  }
    18  
    19  func NewAppSummaryDisplayer2(ui command.UI) *AppSummaryDisplayer2 {
    20  	return &AppSummaryDisplayer2{
    21  		UI: ui,
    22  	}
    23  }
    24  
    25  func (display AppSummaryDisplayer2) AppDisplay(summary v2v3action.ApplicationSummary, displayStartCommand bool) {
    26  	var isoRow []string
    27  	if name, exists := summary.GetIsolationSegmentName(); exists {
    28  		isoRow = append(isoRow, display.UI.TranslateText("isolation segment:"), name)
    29  	}
    30  
    31  	var lifecycleInfo []string
    32  	if summary.LifecycleType == constant.AppLifecycleTypeDocker {
    33  		lifecycleInfo = []string{display.UI.TranslateText("docker image:"), summary.CurrentDroplet.Image}
    34  	} else {
    35  		lifecycleInfo = []string{display.UI.TranslateText("buildpacks:"), display.buildpackNames(summary.CurrentDroplet.Buildpacks)}
    36  	}
    37  
    38  	keyValueTable := [][]string{
    39  		{display.UI.TranslateText("name:"), summary.Application.Name},
    40  		{display.UI.TranslateText("requested state:"), strings.ToLower(string(summary.State))},
    41  		isoRow,
    42  		{display.UI.TranslateText("routes:"), summary.Routes.Summary()},
    43  		{display.UI.TranslateText("last uploaded:"), display.getCreatedTime(summary)},
    44  		{display.UI.TranslateText("stack:"), summary.CurrentDroplet.Stack},
    45  		lifecycleInfo,
    46  	}
    47  
    48  	display.UI.DisplayKeyValueTable("", keyValueTable, 3)
    49  
    50  	display.displayProcessTable(summary.ApplicationSummary, displayStartCommand)
    51  }
    52  
    53  func (display AppSummaryDisplayer2) displayAppInstancesTable(processSummary v3action.ProcessSummary) {
    54  	table := [][]string{
    55  		{
    56  			"",
    57  			display.UI.TranslateText("state"),
    58  			display.UI.TranslateText("since"),
    59  			display.UI.TranslateText("cpu"),
    60  			display.UI.TranslateText("memory"),
    61  			display.UI.TranslateText("disk"),
    62  			display.UI.TranslateText("details"),
    63  		},
    64  	}
    65  
    66  	for _, instance := range processSummary.InstanceDetails {
    67  		table = append(table, []string{
    68  			fmt.Sprintf("#%d", instance.Index),
    69  			display.UI.TranslateText(strings.ToLower(string(instance.State))),
    70  			display.appInstanceDate(instance.StartTime()),
    71  			fmt.Sprintf("%.1f%%", instance.CPU*100),
    72  			display.UI.TranslateText("{{.MemUsage}} of {{.MemQuota}}", map[string]interface{}{
    73  				"MemUsage": bytefmt.ByteSize(instance.MemoryUsage),
    74  				"MemQuota": bytefmt.ByteSize(instance.MemoryQuota),
    75  			}),
    76  			display.UI.TranslateText("{{.DiskUsage}} of {{.DiskQuota}}", map[string]interface{}{
    77  				"DiskUsage": bytefmt.ByteSize(instance.DiskUsage),
    78  				"DiskQuota": bytefmt.ByteSize(instance.DiskQuota),
    79  			}),
    80  			instance.Details,
    81  		})
    82  	}
    83  
    84  	display.UI.DisplayInstancesTableForApp(table)
    85  }
    86  
    87  func (display AppSummaryDisplayer2) displayProcessTable(summary v3action.ApplicationSummary, displayStartCommand bool) {
    88  	for _, process := range summary.ProcessSummaries {
    89  		display.UI.DisplayNewline()
    90  
    91  		var startCommandRow []string
    92  		if displayStartCommand && len(process.Command.Value) > 0 {
    93  			startCommandRow = append(startCommandRow, display.UI.TranslateText("start command:"), process.Command.Value)
    94  		}
    95  
    96  		keyValueTable := [][]string{
    97  			{display.UI.TranslateText("type:"), process.Type},
    98  			{display.UI.TranslateText("instances:"), fmt.Sprintf("%d/%d", process.HealthyInstanceCount(), process.TotalInstanceCount())},
    99  			{display.UI.TranslateText("memory usage:"), fmt.Sprintf("%dM", process.MemoryInMB.Value)},
   100  			startCommandRow,
   101  		}
   102  
   103  		display.UI.DisplayKeyValueTable("", keyValueTable, 3)
   104  
   105  		if len(process.InstanceDetails) == 0 {
   106  			display.UI.DisplayNewline()
   107  			display.UI.DisplayText("There are no running instances of this process.")
   108  			continue
   109  		}
   110  		display.displayAppInstancesTable(process)
   111  	}
   112  }
   113  
   114  func (display AppSummaryDisplayer2) getCreatedTime(summary v2v3action.ApplicationSummary) string {
   115  	if summary.CurrentDroplet.CreatedAt != "" {
   116  		timestamp, _ := time.Parse(time.RFC3339, summary.CurrentDroplet.CreatedAt)
   117  		return display.UI.UserFriendlyDate(timestamp)
   118  	}
   119  
   120  	return ""
   121  }
   122  
   123  func (AppSummaryDisplayer2) usageSummary(processSummaries v3action.ProcessSummaries) string {
   124  	var usageStrings []string
   125  	for _, summary := range processSummaries {
   126  		if summary.TotalInstanceCount() > 0 {
   127  			usageStrings = append(usageStrings, fmt.Sprintf("%dM x %d", summary.MemoryInMB.Value, summary.TotalInstanceCount()))
   128  		}
   129  	}
   130  
   131  	return strings.Join(usageStrings, ", ")
   132  }
   133  
   134  func (AppSummaryDisplayer2) buildpackNames(buildpacks []v3action.Buildpack) string {
   135  	var names []string
   136  	for _, buildpack := range buildpacks {
   137  		if buildpack.DetectOutput != "" {
   138  			names = append(names, buildpack.DetectOutput)
   139  		} else {
   140  			names = append(names, buildpack.Name)
   141  		}
   142  	}
   143  
   144  	return strings.Join(names, ", ")
   145  }
   146  
   147  func (AppSummaryDisplayer2) appInstanceDate(input time.Time) string {
   148  	return input.UTC().Format(time.RFC3339)
   149  }
   150  
   151  func (AppSummaryDisplayer2) processHasAnInstanceUp(processSummary *v3action.ProcessSummary) bool {
   152  	for _, processInstance := range processSummary.InstanceDetails {
   153  		if processInstance.State != constant.ProcessInstanceDown {
   154  			return true
   155  		}
   156  	}
   157  	return false
   158  }
   159  
   160  func (AppSummaryDisplayer2) processInstancesAreAllCrashed(processSummary *v3action.ProcessSummary) bool {
   161  	if len(processSummary.InstanceDetails) < 1 {
   162  		return false
   163  	}
   164  
   165  	for _, processInstance := range processSummary.InstanceDetails {
   166  		if processInstance.State != constant.ProcessInstanceDown {
   167  			return false
   168  		}
   169  	}
   170  	return true
   171  }