github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cluster/printer.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package cluster 21 22 import ( 23 "io" 24 "strings" 25 26 corev1 "k8s.io/api/core/v1" 27 28 "github.com/1aal/kubeblocks/pkg/cli/printer" 29 "github.com/1aal/kubeblocks/pkg/cli/util" 30 ) 31 32 type PrintType string 33 34 const ( 35 PrintClusters PrintType = "clusters" 36 PrintWide PrintType = "wide" 37 PrintInstances PrintType = "instances" 38 PrintComponents PrintType = "components" 39 PrintEvents PrintType = "events" 40 PrintLabels PrintType = "label" 41 ) 42 43 type PrinterOptions struct { 44 ShowLabels bool 45 } 46 47 type tblInfo struct { 48 header []interface{} 49 addRow func(tbl *printer.TablePrinter, objs *ClusterObjects, opt *PrinterOptions) 50 getOptions GetOptions 51 } 52 53 var mapTblInfo = map[PrintType]tblInfo{ 54 PrintClusters: { 55 header: []interface{}{"NAME", "NAMESPACE", "CLUSTER-DEFINITION", "VERSION", "TERMINATION-POLICY", "STATUS", "CREATED-TIME"}, 56 addRow: func(tbl *printer.TablePrinter, objs *ClusterObjects, opt *PrinterOptions) { 57 c := objs.GetClusterInfo() 58 info := []interface{}{c.Name, c.Namespace, c.ClusterDefinition, c.ClusterVersion, c.TerminationPolicy, c.Status, c.CreatedTime} 59 if opt.ShowLabels { 60 info = append(info, c.Labels) 61 } 62 63 tbl.AddRow(info...) 64 }, 65 getOptions: GetOptions{}, 66 }, 67 PrintWide: { 68 header: []interface{}{"NAME", "NAMESPACE", "CLUSTER-DEFINITION", "VERSION", "TERMINATION-POLICY", "STATUS", "INTERNAL-ENDPOINTS", "EXTERNAL-ENDPOINTS", "CREATED-TIME"}, 69 addRow: func(tbl *printer.TablePrinter, objs *ClusterObjects, opt *PrinterOptions) { 70 c := objs.GetClusterInfo() 71 info := []interface{}{c.Name, c.Namespace, c.ClusterDefinition, c.ClusterVersion, c.TerminationPolicy, c.Status, c.InternalEP, c.ExternalEP, c.CreatedTime} 72 if opt.ShowLabels { 73 info = append(info, c.Labels) 74 } 75 tbl.AddRow(info...) 76 }, 77 getOptions: GetOptions{WithClusterDef: true, WithService: true, WithPod: true}, 78 }, 79 PrintInstances: { 80 header: []interface{}{"NAME", "NAMESPACE", "CLUSTER", "COMPONENT", "STATUS", "ROLE", "ACCESSMODE", "AZ", "CPU(REQUEST/LIMIT)", "MEMORY(REQUEST/LIMIT)", "STORAGE", "NODE", "CREATED-TIME"}, 81 addRow: AddInstanceRow, 82 getOptions: GetOptions{WithClusterDef: true, WithPod: true}, 83 }, 84 PrintComponents: { 85 header: []interface{}{"NAME", "NAMESPACE", "CLUSTER", "TYPE", "IMAGE"}, 86 addRow: AddComponentRow, 87 getOptions: GetOptions{WithClusterDef: true, WithPod: true}, 88 }, 89 PrintEvents: { 90 header: []interface{}{"NAMESPACE", "TIME", "TYPE", "REASON", "OBJECT", "MESSAGE"}, 91 addRow: AddEventRow, 92 getOptions: GetOptions{WithClusterDef: true, WithPod: true, WithEvent: true}, 93 }, 94 PrintLabels: { 95 header: []interface{}{"NAME", "NAMESPACE"}, 96 addRow: AddLabelRow, 97 getOptions: GetOptions{}, 98 }, 99 } 100 101 // Printer prints cluster info 102 type Printer struct { 103 tbl *printer.TablePrinter 104 opt *PrinterOptions 105 tblInfo 106 } 107 108 func NewPrinter(out io.Writer, printType PrintType, opt *PrinterOptions) *Printer { 109 p := &Printer{tbl: printer.NewTablePrinter(out)} 110 p.tblInfo = mapTblInfo[printType] 111 112 if opt == nil { 113 opt = &PrinterOptions{} 114 } 115 p.opt = opt 116 117 if opt.ShowLabels { 118 p.tblInfo.header = append(p.tblInfo.header, "LABELS") 119 } 120 121 p.tbl.SetHeader(p.tblInfo.header...) 122 return p 123 } 124 125 func (p *Printer) AddRow(objs *ClusterObjects) { 126 p.addRow(p.tbl, objs, p.opt) 127 } 128 129 func (p *Printer) Print() { 130 p.tbl.Print() 131 } 132 133 func (p *Printer) GetterOptions() GetOptions { 134 return p.getOptions 135 } 136 137 func AddLabelRow(tbl *printer.TablePrinter, objs *ClusterObjects, opt *PrinterOptions) { 138 c := objs.GetClusterInfo() 139 info := []interface{}{c.Name, c.Namespace} 140 if opt.ShowLabels { 141 labels := strings.ReplaceAll(c.Labels, ",", "\n") 142 info = append(info, labels) 143 } 144 tbl.AddRow(info...) 145 } 146 147 func AddComponentRow(tbl *printer.TablePrinter, objs *ClusterObjects, opt *PrinterOptions) { 148 components := objs.GetComponentInfo() 149 for _, c := range components { 150 tbl.AddRow(c.Name, c.NameSpace, c.Cluster, c.Type, c.Image) 151 } 152 } 153 154 func AddInstanceRow(tbl *printer.TablePrinter, objs *ClusterObjects, opt *PrinterOptions) { 155 instances := objs.GetInstanceInfo() 156 for _, instance := range instances { 157 tbl.AddRow(instance.Name, instance.Namespace, instance.Cluster, instance.Component, 158 instance.Status, instance.Role, instance.AccessMode, 159 instance.AZ, instance.CPU, instance.Memory, 160 BuildStorageSize(instance.Storage), instance.Node, instance.CreatedTime) 161 } 162 } 163 164 func AddEventRow(tbl *printer.TablePrinter, objs *ClusterObjects, opt *PrinterOptions) { 165 events := util.SortEventsByLastTimestamp(objs.Events, "") 166 for _, event := range *events { 167 e := event.(*corev1.Event) 168 tbl.AddRow(e.Namespace, util.GetEventTimeStr(e), e.Type, e.Reason, util.GetEventObject(e), e.Message) 169 } 170 }