github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/command/v7/shared/app_summary_displayer.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/v7action" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 11 "code.cloudfoundry.org/cli/command" 12 log "github.com/sirupsen/logrus" 13 ) 14 15 type AppSummaryDisplayer struct { 16 UI command.UI 17 } 18 19 func NewAppSummaryDisplayer(ui command.UI) *AppSummaryDisplayer { 20 return &AppSummaryDisplayer{ 21 UI: ui, 22 } 23 } 24 25 func (display AppSummaryDisplayer) AppDisplay(summary v7action.DetailedApplicationSummary, 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:"), routeSummary(summary.Routes)}, 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, displayStartCommand) 51 } 52 53 func routeSummary(rs []v7action.Route) string { 54 formattedRoutes := []string{} 55 for _, route := range rs { 56 formattedRoutes = append(formattedRoutes, route.URL) 57 } 58 return strings.Join(formattedRoutes, ", ") 59 } 60 61 func (display AppSummaryDisplayer) displayAppInstancesTable(processSummary v7action.ProcessSummary) { 62 table := [][]string{ 63 { 64 "", 65 display.UI.TranslateText("state"), 66 display.UI.TranslateText("since"), 67 display.UI.TranslateText("cpu"), 68 display.UI.TranslateText("memory"), 69 display.UI.TranslateText("disk"), 70 display.UI.TranslateText("details"), 71 }, 72 } 73 74 for _, instance := range processSummary.InstanceDetails { 75 table = append(table, []string{ 76 fmt.Sprintf("#%d", instance.Index), 77 display.UI.TranslateText(strings.ToLower(string(instance.State))), 78 display.appInstanceDate(instance.StartTime()), 79 fmt.Sprintf("%.1f%%", instance.CPU*100), 80 display.UI.TranslateText("{{.MemUsage}} of {{.MemQuota}}", map[string]interface{}{ 81 "MemUsage": bytefmt.ByteSize(instance.MemoryUsage), 82 "MemQuota": bytefmt.ByteSize(instance.MemoryQuota), 83 }), 84 display.UI.TranslateText("{{.DiskUsage}} of {{.DiskQuota}}", map[string]interface{}{ 85 "DiskUsage": bytefmt.ByteSize(instance.DiskUsage), 86 "DiskQuota": bytefmt.ByteSize(instance.DiskQuota), 87 }), 88 instance.Details, 89 }) 90 } 91 92 display.UI.DisplayInstancesTableForApp(table) 93 } 94 95 func (display AppSummaryDisplayer) displayProcessTable(summary v7action.DetailedApplicationSummary, displayStartCommand bool) { 96 for _, process := range summary.ProcessSummaries { 97 display.UI.DisplayNewline() 98 99 var startCommandRow []string 100 if displayStartCommand && len(process.Command.Value) > 0 { 101 startCommandRow = append(startCommandRow, display.UI.TranslateText("start command:"), process.Command.Value) 102 } 103 104 var processSidecars []string 105 for _, sidecar := range process.Sidecars { 106 processSidecars = append(processSidecars, sidecar.Name) 107 } 108 109 keyValueTable := [][]string{ 110 {display.UI.TranslateText("type:"), process.Type}, 111 {display.UI.TranslateText("sidecars:"), strings.Join(processSidecars, ", ")}, 112 {display.UI.TranslateText("instances:"), fmt.Sprintf("%d/%d", process.HealthyInstanceCount(), process.TotalInstanceCount())}, 113 {display.UI.TranslateText("memory usage:"), fmt.Sprintf("%dM", process.MemoryInMB.Value)}, 114 startCommandRow, 115 } 116 117 display.UI.DisplayKeyValueTable("", keyValueTable, 3) 118 119 if len(process.InstanceDetails) == 0 { 120 display.UI.DisplayText("There are no running instances of this process.") 121 continue 122 } 123 display.displayAppInstancesTable(process) 124 } 125 } 126 127 func (display AppSummaryDisplayer) getCreatedTime(summary v7action.DetailedApplicationSummary) string { 128 if summary.CurrentDroplet.CreatedAt != "" { 129 timestamp, err := time.Parse(time.RFC3339, summary.CurrentDroplet.CreatedAt) 130 if err != nil { 131 log.WithField("createdAt", summary.CurrentDroplet.CreatedAt).Errorln("error parsing created at:", err) 132 } 133 134 return display.UI.UserFriendlyDate(timestamp) 135 } 136 137 return "" 138 } 139 140 func (AppSummaryDisplayer) buildpackNames(buildpacks []v7action.DropletBuildpack) string { 141 var names []string 142 for _, buildpack := range buildpacks { 143 if buildpack.DetectOutput != "" { 144 names = append(names, buildpack.DetectOutput) 145 } else { 146 names = append(names, buildpack.Name) 147 } 148 } 149 150 return strings.Join(names, ", ") 151 } 152 153 func (AppSummaryDisplayer) appInstanceDate(input time.Time) string { 154 return input.UTC().Format(time.RFC3339) 155 }