github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/class/list.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 class 21 22 import ( 23 "fmt" 24 "sort" 25 "strings" 26 27 "github.com/spf13/cobra" 28 "k8s.io/apimachinery/pkg/api/resource" 29 "k8s.io/cli-runtime/pkg/genericiooptions" 30 "k8s.io/client-go/dynamic" 31 cmdutil "k8s.io/kubectl/pkg/cmd/util" 32 "k8s.io/kubectl/pkg/util/templates" 33 34 "github.com/1aal/kubeblocks/pkg/class" 35 "github.com/1aal/kubeblocks/pkg/cli/printer" 36 "github.com/1aal/kubeblocks/pkg/cli/util" 37 "github.com/1aal/kubeblocks/pkg/cli/util/flags" 38 ) 39 40 type ListOptions struct { 41 ClusterDefRef string 42 Factory cmdutil.Factory 43 dynamic dynamic.Interface 44 genericiooptions.IOStreams 45 } 46 47 var listClassExamples = templates.Examples(` 48 # List all components classes in cluster definition apecloud-mysql 49 kbcli class list --cluster-definition apecloud-mysql 50 `) 51 52 func NewListCommand(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 53 o := &ListOptions{IOStreams: streams} 54 cmd := &cobra.Command{ 55 Use: "list", 56 Short: "List classes", 57 Example: listClassExamples, 58 Run: func(cmd *cobra.Command, args []string) { 59 util.CheckErr(o.complete(f)) 60 util.CheckErr(o.run()) 61 }, 62 } 63 flags.AddClusterDefinitionFlag(f, cmd, &o.ClusterDefRef) 64 util.CheckErr(cmd.MarkFlagRequired("cluster-definition")) 65 return cmd 66 } 67 68 func (o *ListOptions) complete(f cmdutil.Factory) error { 69 var err error 70 o.dynamic, err = f.DynamicClient() 71 return err 72 } 73 74 func (o *ListOptions) run() error { 75 clsMgr, err := GetManager(o.dynamic, o.ClusterDefRef) 76 if err != nil { 77 return err 78 } 79 for compName, classes := range clsMgr.GetClasses() { 80 o.printClass(compName, classes) 81 } 82 return nil 83 } 84 85 func (o *ListOptions) printClass(compName string, classes []*class.ComponentClassWithRef) { 86 tbl := printer.NewTablePrinter(o.Out) 87 tbl.SetHeader("COMPONENT", "CLASS", "CPU", "MEMORY") 88 sort.Sort(class.ByClassResource(classes)) 89 for _, cls := range classes { 90 tbl.AddRow(compName, cls.Name, cls.CPU.String(), normalizeMemory(cls.Memory)) 91 } 92 tbl.Print() 93 } 94 95 func normalizeMemory(mem resource.Quantity) string { 96 if !strings.HasSuffix(mem.String(), "m") { 97 return mem.String() 98 } 99 100 var ( 101 value float64 102 suffix string 103 bytes = float64(mem.MilliValue()) / 1000 104 ) 105 switch { 106 case bytes < 1024: 107 value = bytes / 1024 108 suffix = "Ki" 109 case bytes < 1024*1024: 110 value = bytes / 1024 / 1024 111 suffix = "Mi" 112 case bytes < 1024*1024*1024: 113 value = bytes / 1024 / 1024 / 1024 114 suffix = "Gi" 115 default: 116 value = bytes / 1024 / 1024 / 1024 / 1024 117 suffix = "Ti" 118 } 119 return strings.TrimRight(fmt.Sprintf("%.3f", value), "0") + suffix 120 }