github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/cluster/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 cluster 21 22 import ( 23 "fmt" 24 25 "github.com/spf13/cobra" 26 "k8s.io/cli-runtime/pkg/genericiooptions" 27 "k8s.io/client-go/dynamic" 28 "k8s.io/client-go/kubernetes" 29 cmdutil "k8s.io/kubectl/pkg/cmd/util" 30 "k8s.io/kubectl/pkg/util/templates" 31 32 "github.com/1aal/kubeblocks/pkg/cli/cluster" 33 "github.com/1aal/kubeblocks/pkg/cli/list" 34 "github.com/1aal/kubeblocks/pkg/cli/printer" 35 "github.com/1aal/kubeblocks/pkg/cli/types" 36 "github.com/1aal/kubeblocks/pkg/cli/util" 37 ) 38 39 var ( 40 listExample = templates.Examples(` 41 # list all clusters 42 kbcli cluster list 43 44 # list a single cluster with specified name 45 kbcli cluster list mycluster 46 47 # list a single cluster in YAML output format 48 kbcli cluster list mycluster -o yaml 49 50 # list a single cluster in JSON output format 51 kbcli cluster list mycluster -o json 52 53 # list a single cluster in wide output format 54 kbcli cluster list mycluster -o wide`) 55 56 listInstancesExample = templates.Examples(` 57 # list all instances of all clusters in current namespace 58 kbcli cluster list-instances 59 60 # list all instances of a specified cluster 61 kbcli cluster list-instances mycluster`) 62 63 listComponentsExample = templates.Examples(` 64 # list all components of all clusters in current namespace 65 kbcli cluster list-components 66 67 # list all components of a specified cluster 68 kbcli cluster list-components mycluster`) 69 70 listEventsExample = templates.Examples(` 71 # list all events of all clusters in current namespace 72 kbcli cluster list-events 73 74 # list all events of a specified cluster 75 kbcli cluster list-events mycluster`) 76 ) 77 78 func NewListCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 79 o := list.NewListOptions(f, streams, types.ClusterGVR()) 80 cmd := &cobra.Command{ 81 Use: "list [NAME]", 82 Short: "List clusters.", 83 Example: listExample, 84 Aliases: []string{"ls"}, 85 ValidArgsFunction: util.ResourceNameCompletionFunc(f, o.GVR), 86 Run: func(cmd *cobra.Command, args []string) { 87 o.Names = args 88 if o.Format == printer.Wide { 89 util.CheckErr(run(o, cluster.PrintWide)) 90 } else { 91 util.CheckErr(run(o, cluster.PrintClusters)) 92 } 93 }, 94 } 95 o.AddFlags(cmd) 96 return cmd 97 } 98 99 func NewListInstancesCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 100 o := list.NewListOptions(f, streams, types.ClusterGVR()) 101 cmd := &cobra.Command{ 102 Use: "list-instances", 103 Short: "List cluster instances.", 104 Example: listInstancesExample, 105 Aliases: []string{"ls-instances"}, 106 ValidArgsFunction: util.ResourceNameCompletionFunc(f, o.GVR), 107 Run: func(cmd *cobra.Command, args []string) { 108 o.Names = args 109 util.CheckErr(run(o, cluster.PrintInstances)) 110 }, 111 } 112 cmd.Flags().BoolVarP(&o.AllNamespaces, "all-namespaces", "A", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.") 113 cmd.Flags().StringVarP(&o.LabelSelector, "selector", "l", o.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Matching objects must satisfy all of the specified label constraints.") 114 return cmd 115 } 116 117 func NewListComponentsCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 118 o := list.NewListOptions(f, streams, types.ClusterGVR()) 119 cmd := &cobra.Command{ 120 Use: "list-components", 121 Short: "List cluster components.", 122 Example: listComponentsExample, 123 Aliases: []string{"ls-components"}, 124 ValidArgsFunction: util.ResourceNameCompletionFunc(f, o.GVR), 125 Run: func(cmd *cobra.Command, args []string) { 126 o.Names = args 127 util.CheckErr(run(o, cluster.PrintComponents)) 128 }, 129 } 130 cmd.Flags().BoolVarP(&o.AllNamespaces, "all-namespaces", "A", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.") 131 cmd.Flags().StringVarP(&o.LabelSelector, "selector", "l", o.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Matching objects must satisfy all of the specified label constraints.") 132 return cmd 133 } 134 135 func NewListEventsCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command { 136 o := list.NewListOptions(f, streams, types.ClusterGVR()) 137 cmd := &cobra.Command{ 138 Use: "list-events", 139 Short: "List cluster events.", 140 Example: listEventsExample, 141 Aliases: []string{"ls-events"}, 142 ValidArgsFunction: util.ResourceNameCompletionFunc(f, o.GVR), 143 Run: func(cmd *cobra.Command, args []string) { 144 o.Names = args 145 util.CheckErr(run(o, cluster.PrintEvents)) 146 }, 147 } 148 cmd.Flags().BoolVarP(&o.AllNamespaces, "all-namespaces", "A", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.") 149 cmd.Flags().StringVarP(&o.LabelSelector, "selector", "l", o.LabelSelector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2). Matching objects must satisfy all of the specified label constraints.") 150 return cmd 151 } 152 153 func run(o *list.ListOptions, printType cluster.PrintType) error { 154 // if format is JSON or YAML, use default printer to output the result. 155 if o.Format == printer.JSON || o.Format == printer.YAML { 156 _, err := o.Run() 157 return err 158 } 159 160 // get and output the result 161 o.Print = false 162 r, err := o.Run() 163 if err != nil { 164 return err 165 } 166 167 infos, err := r.Infos() 168 if err != nil { 169 return err 170 } 171 172 if len(infos) == 0 { 173 fmt.Fprintln(o.IOStreams.Out, "No cluster found") 174 return nil 175 } 176 177 dynamic, err := o.Factory.DynamicClient() 178 if err != nil { 179 return err 180 } 181 182 client, err := o.Factory.KubernetesClientSet() 183 if err != nil { 184 return err 185 } 186 187 opt := &cluster.PrinterOptions{ 188 ShowLabels: o.ShowLabels, 189 } 190 191 p := cluster.NewPrinter(o.IOStreams.Out, printType, opt) 192 for _, info := range infos { 193 if err = addRow(dynamic, client, info.Namespace, info.Name, p); err != nil { 194 return err 195 } 196 } 197 p.Print() 198 return nil 199 } 200 201 func addRow(dynamic dynamic.Interface, client *kubernetes.Clientset, 202 namespace string, name string, printer *cluster.Printer) error { 203 getter := &cluster.ObjectsGetter{ 204 Name: name, 205 Namespace: namespace, 206 Client: client, 207 Dynamic: dynamic, 208 GetOptions: printer.GetterOptions(), 209 } 210 211 clusterObjs, err := getter.Get() 212 if err != nil { 213 return err 214 } 215 216 printer.AddRow(clusterObjs) 217 return nil 218 }