...

Source file src/github.com/chaos-mesh/chaos-mesh/pkg/chaosctl/cmd/debug.go

Documentation: github.com/chaos-mesh/chaos-mesh/pkg/chaosctl/cmd

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  package cmd
    17  
    18  import (
    19  	"context"
    20  	"fmt"
    21  
    22  	"github.com/go-logr/logr"
    23  	"github.com/pkg/errors"
    24  	"github.com/spf13/cobra"
    25  
    26  	"github.com/chaos-mesh/chaos-mesh/pkg/chaosctl/common"
    27  	"github.com/chaos-mesh/chaos-mesh/pkg/chaosctl/debug"
    28  )
    29  
    30  type DebugOptions struct {
    31  	namespace string
    32  }
    33  
    34  const (
    35  	networkChaos = "networkchaos"
    36  	stressChaos  = "stresschaos"
    37  	ioChaos      = "iochaos"
    38  	httpChaos    = "httpchaos"
    39  )
    40  
    41  func NewDebugCommand(logger logr.Logger, debugs map[string]debug.Debug) (*cobra.Command, error) {
    42  	o := &DebugOptions{}
    43  
    44  	debugCmd := &cobra.Command{
    45  		Use:   `debug (CHAOSTYPE) [-c CHAOSNAME] [-n NAMESPACE]`,
    46  		Short: `Print the debug information for certain chaos`,
    47  		Long: `Print the debug information for certain chaos.
    48  Currently support networkchaos, stresschaos, iochaos and httpchaos.
    49  
    50  Examples:
    51    # Return debug information from all networkchaos in default namespace
    52    chaosctl debug networkchaos
    53  
    54    # Return debug information from certain networkchaos
    55    chaosctl debug networkchaos CHAOSNAME -n NAMESPACE`,
    56  		ValidArgsFunction: noCompletions,
    57  	}
    58  
    59  	for chaosType, debug := range debugs {
    60  		debugCmd.AddCommand(debugResourceCommand(o, chaosType, debug))
    61  	}
    62  
    63  	debugCmd.PersistentFlags().StringVarP(&o.namespace, "namespace", "n", "default", "namespace to find chaos")
    64  	err := debugCmd.RegisterFlagCompletionFunc("namespace", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    65  		client, cancel, err := common.CreateClient(context.TODO(), managerNamespace, managerSvc)
    66  		if err != nil {
    67  			logger.Error(err, "fail to create client")
    68  			return nil, cobra.ShellCompDirectiveNoFileComp
    69  		}
    70  		defer cancel()
    71  
    72  		completion, err := client.ListNamespace(context.TODO())
    73  		if err != nil {
    74  			logger.Error(err, "fail to complete resource")
    75  			return nil, cobra.ShellCompDirectiveNoFileComp
    76  		}
    77  
    78  		return completion, cobra.ShellCompDirectiveNoFileComp | cobra.ShellCompDirectiveNoSpace
    79  	})
    80  	return debugCmd, err
    81  }
    82  
    83  func debugResourceCommand(option *DebugOptions, chaosType string, debug debug.Debug) *cobra.Command {
    84  	return &cobra.Command{
    85  		Use:   fmt.Sprintf(`%s (CHAOSNAME) [-n NAMESPACE]`, chaosType),
    86  		Short: fmt.Sprintf(`Print the debug information for certain %s`, chaosType),
    87  		Long:  fmt.Sprintf(`Print the debug information for certain %s`, chaosType),
    88  		RunE: func(cmd *cobra.Command, args []string) error {
    89  			client, cancel, err := common.CreateClient(context.TODO(), managerNamespace, managerSvc)
    90  			if err != nil {
    91  				return err
    92  			}
    93  			defer cancel()
    94  			return option.Run(debug(client), args)
    95  		},
    96  		SilenceErrors: true,
    97  		SilenceUsage:  true,
    98  		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    99  			if len(args) != 0 {
   100  				return []string{}, cobra.ShellCompDirectiveNoFileComp
   101  			}
   102  			client, cancel, err := common.CreateClient(context.TODO(), managerNamespace, managerSvc)
   103  			if err != nil {
   104  				common.PrettyPrint(errors.Wrap(err, "create client").Error(), 0, common.Red)
   105  				return nil, cobra.ShellCompDirectiveNoFileComp
   106  			}
   107  			defer cancel()
   108  			return option.List(debug(client))
   109  		},
   110  	}
   111  }
   112  
   113  // Run debug
   114  func (o *DebugOptions) Run(debugger debug.Debugger, args []string) error {
   115  	if len(args) > 1 {
   116  		return errors.New("only one chaos could be specified")
   117  	}
   118  	ctx, cancel := context.WithCancel(context.Background())
   119  	defer cancel()
   120  
   121  	chaosName := ""
   122  	if len(args) == 1 {
   123  		chaosName = args[0]
   124  	}
   125  
   126  	var result []*common.ChaosResult
   127  	var err error
   128  
   129  	result, err = debugger.Collect(ctx, o.namespace, chaosName)
   130  	if err != nil {
   131  		return err
   132  	}
   133  
   134  	common.PrintResult(result)
   135  	return nil
   136  }
   137  
   138  // Run debug
   139  func (o *DebugOptions) List(debugger debug.Debugger) ([]string, cobra.ShellCompDirective) {
   140  	ctx, cancel := context.WithCancel(context.Background())
   141  	defer cancel()
   142  
   143  	chaos, err := debugger.List(ctx, o.namespace)
   144  	if err != nil {
   145  		common.PrettyPrint(errors.Wrap(err, "list chaos").Error(), 0, common.Red)
   146  		return nil, cobra.ShellCompDirectiveNoFileComp
   147  	}
   148  
   149  	return chaos, cobra.ShellCompDirectiveNoFileComp
   150  }
   151