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  }