github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/test/e2e/util/common.go (about)

     1  /*
     2  Copyright the Velero contributors.
     3  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     4  
     5  Licensed under the Apache License, Version 2.0 (the "License");
     6  you may not use this file except in compliance with the License.
     7  You may obtain a copy of the License at
     8  
     9      http://www.apache.org/licenses/LICENSE-2.0
    10  
    11  Unless required by applicable law or agreed to in writing, software
    12  distributed under the License is distributed on an "AS IS" BASIS,
    13  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  See the License for the specific language governing permissions and
    15  limitations under the License.
    16  */
    17  
    18  package util
    19  
    20  import (
    21  	"fmt"
    22  	"io/ioutil"
    23  	"os/exec"
    24  	"time"
    25  
    26  	"github.com/pkg/errors"
    27  	"github.com/vmware-tanzu/velero/pkg/builder"
    28  	veleroexec "github.com/vmware-tanzu/velero/pkg/util/exec"
    29  	"github.com/vmware-tanzu/velero/test/e2e/util/common"
    30  	"golang.org/x/net/context"
    31  	corev1api "k8s.io/api/core/v1"
    32  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    33  	"k8s.io/apimachinery/pkg/util/wait"
    34  
    35  	"github.com/1aal/kubeblocks/pkg/constant"
    36  	"github.com/1aal/kubeblocks/test/testutils"
    37  )
    38  
    39  func EnsureClusterExists(ctx context.Context) error {
    40  	return exec.CommandContext(ctx, "kubectl", "cluster-info").Run()
    41  }
    42  
    43  func CreateSecretFromFiles(ctx context.Context, client TestClient, namespace string, name string, files map[string]string) error {
    44  	data := make(map[string][]byte)
    45  
    46  	for key, filePath := range files {
    47  		contents, err := ioutil.ReadFile(filePath)
    48  		if err != nil {
    49  			return errors.WithMessagef(err, "Failed to read secret file %q", filePath)
    50  		}
    51  
    52  		data[key] = contents
    53  	}
    54  	secret := builder.ForSecret(namespace, name).Data(data).Result()
    55  	_, err := client.ClientGo.CoreV1().Secrets(namespace).Create(ctx, secret, metav1.CreateOptions{})
    56  	return err
    57  }
    58  
    59  // WaitForPods waits till all pods arrive at PodRunning state
    60  func WaitForPods(ctx context.Context, client TestClient, namespace string, pods []string) error {
    61  	timeout := 5 * time.Minute
    62  	interval := 5 * time.Second
    63  	err := wait.PollImmediate(interval, timeout, func() (bool, error) {
    64  		for _, podName := range pods {
    65  			checkPod, err := client.ClientGo.CoreV1().Pods(namespace).Get(context.TODO(), podName, metav1.GetOptions{})
    66  			if err != nil {
    67  				fmt.Println(errors.Wrap(err, fmt.Sprintf("Failed to verify pod %s/%s is %s, try again...\n", namespace, podName, corev1api.PodRunning)))
    68  				return false, nil
    69  			}
    70  			// If any pod is still waiting, no need to check, just return and wait for next poll interval
    71  			if checkPod.Status.Phase != corev1api.PodRunning {
    72  				fmt.Printf("Pod %s is in state %s waiting for it to be %s\n", podName, checkPod.Status.Phase, corev1api.PodRunning)
    73  				return false, nil
    74  			}
    75  		}
    76  		// All pods were in PodRunning state
    77  		return true, nil
    78  	})
    79  	if err != nil {
    80  		return errors.Wrapf(err, fmt.Sprintf("Failed to wait for pods in namespace %s to start running", namespace))
    81  	}
    82  	return nil
    83  }
    84  
    85  func GetPvcByPodName(ctx context.Context, namespace, podName string) ([]string, error) {
    86  	// Example:
    87  	//    NAME                                  STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS             AGE
    88  	//    kibishii-data-kibishii-deployment-0   Bound    pvc-94b9fdf2-c30f-4a7b-87bf-06eadca0d5b6   1Gi        RWO            kibishii-storage-class   115s
    89  	cmds := []*common.OsCommandLine{}
    90  	cmd := &common.OsCommandLine{
    91  		Cmd:  "kubectl",
    92  		Args: []string{"get", "pvc", "-n", namespace},
    93  	}
    94  	cmds = append(cmds, cmd)
    95  
    96  	cmd = &common.OsCommandLine{
    97  		Cmd:  "grep",
    98  		Args: []string{podName},
    99  	}
   100  	cmds = append(cmds, cmd)
   101  
   102  	cmd = &common.OsCommandLine{
   103  		Cmd:  "awk",
   104  		Args: []string{"{print $1}"},
   105  	}
   106  	cmds = append(cmds, cmd)
   107  
   108  	return common.GetListByCmdPipes(ctx, cmds)
   109  }
   110  
   111  func GetPvByPvc(ctx context.Context, namespace, pvc string) ([]string, error) {
   112  	// Example:
   113  	// 	  NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                                              STORAGECLASS             REASON   AGE
   114  	//    pvc-3f784366-58db-40b2-8fec-77307807e74b   1Gi        RWO            Delete           Bound    bsl-deletion/kibishii-data-kibishii-deployment-0   kibishii-storage-class            6h41m
   115  	cmds := []*common.OsCommandLine{}
   116  	cmd := &common.OsCommandLine{
   117  		Cmd:  "kubectl",
   118  		Args: []string{"get", "pv"},
   119  	}
   120  	cmds = append(cmds, cmd)
   121  
   122  	cmd = &common.OsCommandLine{
   123  		Cmd:  "grep",
   124  		Args: []string{namespace + "/" + pvc},
   125  	}
   126  	cmds = append(cmds, cmd)
   127  
   128  	cmd = &common.OsCommandLine{
   129  		Cmd:  "awk",
   130  		Args: []string{"{print $1}"},
   131  	}
   132  	cmds = append(cmds, cmd)
   133  
   134  	return common.GetListByCmdPipes(ctx, cmds)
   135  }
   136  
   137  func CRDShouldExist(ctx context.Context, name string) error {
   138  	return CRDCountShouldBe(ctx, name, 1)
   139  }
   140  
   141  func CRDShouldNotExist(ctx context.Context, name string) error {
   142  	return CRDCountShouldBe(ctx, name, 0)
   143  }
   144  
   145  func CRDCountShouldBe(ctx context.Context, name string, count int) error {
   146  	crdList, err := GetCRD(ctx, name)
   147  	if err != nil {
   148  		return errors.Wrap(err, "Fail to get CRDs")
   149  	}
   150  	len := len(crdList)
   151  	if len != count {
   152  		return errors.New(fmt.Sprintf("CRD count is expected as %d instead of %d", count, len))
   153  	}
   154  	return nil
   155  }
   156  
   157  func GetCRD(ctx context.Context, name string) ([]string, error) {
   158  	cmds := []*common.OsCommandLine{}
   159  	cmd := &common.OsCommandLine{
   160  		Cmd:  "kubectl",
   161  		Args: []string{"get", "crd"},
   162  	}
   163  	cmds = append(cmds, cmd)
   164  
   165  	cmd = &common.OsCommandLine{
   166  		Cmd:  "grep",
   167  		Args: []string{name},
   168  	}
   169  	cmds = append(cmds, cmd)
   170  
   171  	cmd = &common.OsCommandLine{
   172  		Cmd:  "awk",
   173  		Args: []string{"{print $1}"},
   174  	}
   175  	cmds = append(cmds, cmd)
   176  
   177  	return common.GetListByCmdPipes(ctx, cmds)
   178  }
   179  
   180  func AddLabelToPv(ctx context.Context, pv, label string) error {
   181  	return exec.CommandContext(ctx, "kubectl", "label", "pv", pv, label).Run()
   182  }
   183  
   184  func AddLabelToPvc(ctx context.Context, pvc, namespace, label string) error {
   185  	args := []string{"label", "pvc", pvc, "-n", namespace, label}
   186  	fmt.Println(args)
   187  	return exec.CommandContext(ctx, "kubectl", args...).Run()
   188  }
   189  
   190  func AddLabelToPod(ctx context.Context, podName, namespace, label string) error {
   191  	args := []string{"label", "pod", podName, "-n", namespace, label}
   192  	fmt.Println(args)
   193  	return exec.CommandContext(ctx, "kubectl", args...).Run()
   194  }
   195  
   196  func AddLabelToCRD(ctx context.Context, crd, label string) error {
   197  	args := []string{"label", "crd", crd, label}
   198  	fmt.Println(args)
   199  	return exec.CommandContext(ctx, "kubectl", args...).Run()
   200  }
   201  
   202  func KubectlApplyByFile(ctx context.Context, file string) error {
   203  	args := []string{"apply", "-f", file, "--force=true"}
   204  	return exec.CommandContext(ctx, "kubectl", args...).Run()
   205  }
   206  
   207  func KubectlConfigUseContext(ctx context.Context, kubectlContext string) error {
   208  	cmd := exec.CommandContext(ctx, "kubectl",
   209  		"config", "use-context", kubectlContext)
   210  	fmt.Printf("Kubectl config use-context cmd =%v\n", cmd)
   211  	stdout, stderr, err := veleroexec.RunCommand(cmd)
   212  	fmt.Print(stdout)
   213  	fmt.Print(stderr)
   214  	return err
   215  }
   216  
   217  func GetAPIVersions(client *TestClient, name string) ([]string, error) {
   218  	var version []string
   219  	APIGroup, err := client.ClientGo.Discovery().ServerGroups()
   220  	if err != nil {
   221  		return nil, errors.Wrap(err, "Fail to get server API groups")
   222  	}
   223  	for _, group := range APIGroup.Groups {
   224  		fmt.Println(group.Name)
   225  		if group.Name == name {
   226  			for _, v := range group.Versions {
   227  				fmt.Println(v.Version)
   228  				version = append(version, v.Version)
   229  			}
   230  			return version, nil
   231  		}
   232  	}
   233  	return nil, errors.New("Server API groups is empty")
   234  }
   235  
   236  func CreateFileToPod(ctx context.Context, namespace, podName, volume, filename, content string) error {
   237  	arg := []string{"exec", "-n", namespace, "-c", podName, podName,
   238  		"--", "/bin/sh", "-c", fmt.Sprintf("echo ns-%s pod-%s volume-%s  > /%s/%s", namespace, podName, volume, volume, filename)}
   239  	cmd := exec.CommandContext(ctx, "kubectl", arg...)
   240  	fmt.Printf("Kubectl exec cmd =%v\n", cmd)
   241  	return cmd.Run()
   242  }
   243  func ReadFileFromPodVolume(ctx context.Context, namespace, podName, volume, filename string) (string, error) {
   244  	arg := []string{"exec", "-n", namespace, "-c", podName, podName,
   245  		"--", "cat", fmt.Sprintf("/%s/%s", volume, filename)}
   246  	cmd := exec.CommandContext(ctx, "kubectl", arg...)
   247  	fmt.Printf("Kubectl exec cmd =%v\n", cmd)
   248  	stdout, stderr, err := veleroexec.RunCommand(cmd)
   249  	fmt.Print(stdout)
   250  	fmt.Print(stderr)
   251  	return stdout, err
   252  }
   253  
   254  func KubectlGetInfo(cmdName string, arg []string) {
   255  	cmd := exec.CommandContext(context.Background(), cmdName, arg...)
   256  	fmt.Printf("Kubectl exec cmd =%v\n", cmd)
   257  	stdout, stderr, err := veleroexec.RunCommand(cmd)
   258  	fmt.Println(stdout)
   259  	if err != nil {
   260  		fmt.Println(stderr)
   261  		fmt.Println(err)
   262  	}
   263  }
   264  
   265  func DeleteVeleroDs(ctx context.Context) error {
   266  	args := []string{"delete", "ds", "-n", "velero", "--all", "--force", "--grace-period", "0"}
   267  	fmt.Println(args)
   268  	return exec.CommandContext(ctx, "kubectl", args...).Run()
   269  }
   270  
   271  func WaitForCRDEstablished(crdName string) error {
   272  	arg := []string{"wait", "--for", "condition=established", "--timeout=60s", "crd/" + crdName}
   273  	cmd := exec.CommandContext(context.Background(), "kubectl", arg...)
   274  	fmt.Printf("Kubectl exec cmd =%v\n", cmd)
   275  	stdout, stderr, err := veleroexec.RunCommand(cmd)
   276  	fmt.Println(stdout)
   277  	if err != nil {
   278  		fmt.Println(stderr)
   279  		fmt.Println(err)
   280  		return err
   281  	}
   282  	return nil
   283  }
   284  
   285  func BuildAddonLabelSelector() string {
   286  	return fmt.Sprintf("%s=%s,%s=%s",
   287  		constant.AppInstanceLabelKey, testutils.KubeBlocksReleaseName,
   288  		constant.AppNameLabelKey, testutils.KubeBlocksChartName)
   289  }