...

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

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

     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 common
    17  
    18  import (
    19  	"encoding/json"
    20  	"fmt"
    21  	"regexp"
    22  
    23  	"github.com/fatih/color"
    24  	"github.com/pkg/errors"
    25  	"k8s.io/apimachinery/pkg/runtime"
    26  	"k8s.io/client-go/kubernetes"
    27  	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
    28  	"sigs.k8s.io/controller-runtime/pkg/client"
    29  	"sigs.k8s.io/controller-runtime/pkg/client/config"
    30  
    31  	"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
    32  )
    33  
    34  type Color string
    35  
    36  const (
    37  	Blue    Color = "Blue"
    38  	Red     Color = "Red"
    39  	Green   Color = "Green"
    40  	Cyan    Color = "Cyan"
    41  	NoColor Color = ""
    42  )
    43  
    44  var (
    45  	colorFunc = map[Color]func(string, ...interface{}){
    46  		Blue:  color.Blue,
    47  		Red:   color.Red,
    48  		Green: color.Green,
    49  		Cyan:  color.Cyan,
    50  	}
    51  	scheme = runtime.NewScheme()
    52  )
    53  
    54  // ClientSet contains two different clients
    55  type ClientSet struct {
    56  	CtrlCli client.Client
    57  	KubeCli *kubernetes.Clientset
    58  }
    59  
    60  type ChaosResult struct {
    61  	Name string
    62  	Pods []PodResult
    63  }
    64  
    65  type PodResult struct {
    66  	Name  string
    67  	Items []ItemResult
    68  }
    69  
    70  const (
    71  	ItemSuccess = iota + 1
    72  	ItemFailure
    73  )
    74  
    75  type ItemResult struct {
    76  	Name    string
    77  	Value   string
    78  	Status  int    `json:",omitempty"`
    79  	SucInfo string `json:",omitempty"`
    80  	ErrInfo string `json:",omitempty"`
    81  }
    82  
    83  func init() {
    84  	_ = v1alpha1.AddToScheme(scheme)
    85  	_ = clientgoscheme.AddToScheme(scheme)
    86  }
    87  
    88  // PrettyPrint print with tab number and color
    89  func PrettyPrint(s string, indentLevel int, color Color) {
    90  	var tabStr string
    91  	for i := 0; i < indentLevel; i++ {
    92  		tabStr += "\t"
    93  	}
    94  	str := fmt.Sprintf("%s%s\n\n", tabStr, regexp.MustCompile("\n").ReplaceAllString(s, "\n"+tabStr))
    95  	if color != NoColor {
    96  		if cfunc, ok := colorFunc[color]; !ok {
    97  			fmt.Print("COLOR NOT SUPPORTED")
    98  		} else {
    99  			cfunc(str)
   100  		}
   101  	} else {
   102  		fmt.Print(str)
   103  	}
   104  }
   105  
   106  // PrintResult prints result to users in prettier format
   107  func PrintResult(result []*ChaosResult) {
   108  	for _, chaos := range result {
   109  		PrettyPrint("[Chaos]: "+chaos.Name, 0, Blue)
   110  		for _, pod := range chaos.Pods {
   111  			PrettyPrint("[Pod]: "+pod.Name, 0, Blue)
   112  			for i, item := range pod.Items {
   113  				PrettyPrint(fmt.Sprintf("%d. [%s]", i+1, item.Name), 1, Cyan)
   114  				PrettyPrint(item.Value, 1, NoColor)
   115  				if item.Status == ItemSuccess {
   116  					if item.SucInfo != "" {
   117  						PrettyPrint(item.SucInfo, 1, Green)
   118  					} else {
   119  						PrettyPrint("Execute as expected", 1, Green)
   120  					}
   121  				} else if item.Status == ItemFailure {
   122  					PrettyPrint(fmt.Sprintf("Failed: %s ", item.ErrInfo), 1, Red)
   123  				}
   124  			}
   125  		}
   126  	}
   127  }
   128  
   129  // MarshalChaos returns json in readable format
   130  func MarshalChaos(s interface{}) (string, error) {
   131  	b, err := json.MarshalIndent(s, "", "  ")
   132  	if err != nil {
   133  		return "", errors.Wrap(err, "failed to marshal indent")
   134  	}
   135  	return string(b), nil
   136  }
   137  
   138  // InitClientSet inits two different clients that would be used
   139  func InitClientSet() (*ClientSet, error) {
   140  	restconfig, err := config.GetConfig()
   141  	if err != nil {
   142  		return nil, err
   143  	}
   144  	ctrlClient, err := client.New(restconfig, client.Options{Scheme: scheme})
   145  	if err != nil {
   146  		return nil, errors.New("failed to create client")
   147  	}
   148  	kubeClient, err := kubernetes.NewForConfig(restconfig)
   149  	if err != nil {
   150  		return nil, errors.Wrap(err, "error in getting acess to k8s")
   151  	}
   152  	return &ClientSet{ctrlClient, kubeClient}, nil
   153  }
   154