github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/cmd/fault/fault_pod.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 fault
    21  
    22  import (
    23  	"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
    24  	"github.com/spf13/cobra"
    25  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    26  	"k8s.io/apimachinery/pkg/runtime"
    27  	"k8s.io/cli-runtime/pkg/genericiooptions"
    28  	cmdutil "k8s.io/kubectl/pkg/cmd/util"
    29  	"k8s.io/kubectl/pkg/util/templates"
    30  
    31  	"github.com/1aal/kubeblocks/pkg/cli/create"
    32  	"github.com/1aal/kubeblocks/pkg/cli/util"
    33  )
    34  
    35  var faultPodExample = templates.Examples(`
    36  	# kill all pods in default namespace
    37  	kbcli fault pod kill
    38  	
    39  	# kill any pod in default namespace
    40  	kbcli fault pod kill --mode=one
    41  
    42  	# kill two pods in default namespace
    43  	kbcli fault pod kill --mode=fixed --value=2
    44  
    45  	# kill 50% pods in default namespace
    46  	kbcli fault pod kill --mode=percentage --value=50
    47  
    48  	# kill mysql-cluster-mysql-0 pod in default namespace
    49  	kbcli fault pod kill mysql-cluster-mysql-0
    50  
    51  	# kill all pods in default namespace
    52  	kbcli fault pod kill --ns-fault="default"
    53  
    54  	# --label is required to specify the pods that need to be killed. 
    55  	kbcli fault pod kill --label statefulset.kubernetes.io/pod-name=mysql-cluster-mysql-2
    56  
    57  	# kill pod under the specified node.
    58  	kbcli fault pod kill --node=minikube-m02
    59  	
    60  	# kill pod under the specified node-label.
    61  	kbcli fault pod kill --node-label=kubernetes.io/arch=arm64
    62  
    63  	# Allow the experiment to last for one minute.
    64  	kbcli fault pod failure --duration=1m
    65  
    66  	# kill container in pod
    67  	kbcli fault pod kill-container mysql-cluster-mysql-0 --container=mysql
    68  `)
    69  
    70  type PodChaosOptions struct {
    71  	// GracePeriod waiting time, after which fault injection is performed
    72  	GracePeriod    int64    `json:"gracePeriod"`
    73  	ContainerNames []string `json:"containerNames,omitempty"`
    74  
    75  	FaultBaseOptions
    76  }
    77  
    78  func NewPodChaosOptions(f cmdutil.Factory, streams genericiooptions.IOStreams, action string) *PodChaosOptions {
    79  	o := &PodChaosOptions{
    80  		FaultBaseOptions: FaultBaseOptions{
    81  			CreateOptions: create.CreateOptions{
    82  				Factory:         f,
    83  				IOStreams:       streams,
    84  				CueTemplateName: CueTemplatePodChaos,
    85  				GVR:             GetGVR(Group, Version, ResourcePodChaos),
    86  			},
    87  			Action: action,
    88  		},
    89  	}
    90  	o.CreateOptions.PreCreate = o.PreCreate
    91  	o.CreateOptions.Options = o
    92  	return o
    93  }
    94  
    95  func NewPodChaosCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
    96  	cmd := &cobra.Command{
    97  		Use:   "pod",
    98  		Short: "Pod chaos.",
    99  	}
   100  	cmd.AddCommand(
   101  		NewPodKillCmd(f, streams),
   102  		NewPodFailureCmd(f, streams),
   103  		NewContainerKillCmd(f, streams),
   104  	)
   105  	return cmd
   106  }
   107  
   108  func NewPodKillCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
   109  	o := NewPodChaosOptions(f, streams, string(v1alpha1.PodKillAction))
   110  	cmd := o.NewCobraCommand(Kill, KillShort)
   111  
   112  	o.AddCommonFlag(cmd)
   113  	cmd.Flags().Int64VarP(&o.GracePeriod, "grace-period", "g", 0, "Grace period represents the duration in seconds before the pod should be killed")
   114  
   115  	// register flag completion func
   116  	registerFlagCompletionFunc(cmd, f)
   117  
   118  	return cmd
   119  }
   120  
   121  func NewPodFailureCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
   122  	o := NewPodChaosOptions(f, streams, string(v1alpha1.PodFailureAction))
   123  	cmd := o.NewCobraCommand(Failure, FailureShort)
   124  
   125  	o.AddCommonFlag(cmd)
   126  	// register flag completion func
   127  	registerFlagCompletionFunc(cmd, f)
   128  
   129  	return cmd
   130  }
   131  
   132  func NewContainerKillCmd(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
   133  	o := NewPodChaosOptions(f, streams, string(v1alpha1.ContainerKillAction))
   134  	cmd := o.NewCobraCommand(KillContainer, KillContainerShort)
   135  
   136  	o.AddCommonFlag(cmd)
   137  	cmd.Flags().StringArrayVarP(&o.ContainerNames, "container", "c", nil, "the name of the container you want to kill, such as mysql, prometheus.")
   138  
   139  	util.CheckErr(cmd.MarkFlagRequired("container"))
   140  
   141  	// register flag completion func
   142  	registerFlagCompletionFunc(cmd, f)
   143  
   144  	return cmd
   145  }
   146  
   147  func (o *PodChaosOptions) NewCobraCommand(use, short string) *cobra.Command {
   148  	return &cobra.Command{
   149  		Use:     use,
   150  		Short:   short,
   151  		Example: faultPodExample,
   152  		Run: func(cmd *cobra.Command, args []string) {
   153  			o.Args = args
   154  			cmdutil.CheckErr(o.CreateOptions.Complete())
   155  			cmdutil.CheckErr(o.Validate())
   156  			cmdutil.CheckErr(o.Complete())
   157  			cmdutil.CheckErr(o.Run())
   158  		},
   159  	}
   160  }
   161  
   162  func (o *PodChaosOptions) AddCommonFlag(cmd *cobra.Command) {
   163  	o.FaultBaseOptions.AddCommonFlag(cmd)
   164  }
   165  
   166  func (o *PodChaosOptions) Validate() error {
   167  	return o.BaseValidate()
   168  }
   169  
   170  func (o *PodChaosOptions) Complete() error {
   171  	return o.BaseComplete()
   172  }
   173  
   174  func (o *PodChaosOptions) PreCreate(obj *unstructured.Unstructured) error {
   175  	c := &v1alpha1.PodChaos{}
   176  	if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, c); err != nil {
   177  		return err
   178  	}
   179  
   180  	data, e := runtime.DefaultUnstructuredConverter.ToUnstructured(c)
   181  	if e != nil {
   182  		return e
   183  	}
   184  	obj.SetUnstructuredContent(data)
   185  	return nil
   186  }