dev-tools/mage/kubernetes/kind.go (120 lines of code) (raw):

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one // or more contributor license agreements. Licensed under the Elastic License 2.0; // you may not use this file except in compliance with the Elastic License 2.0. package kubernetes import ( "fmt" "io" "os" "os/exec" "path/filepath" "github.com/magefile/mage/mg" "github.com/magefile/mage/sh" ) // KindIntegrationTestStep setups a kind environment. type KindIntegrationTestStep struct{} // Name returns the kind name. func (m *KindIntegrationTestStep) Name() string { return "kind" } // Use always returns false. // // This step should be defined in `StepRequirements` for the tester, for it // to be used. It cannot be autodiscovered for usage. func (m *KindIntegrationTestStep) Use(dir string) (bool, error) { return false, nil } // Setup ensures that a kubernetes cluster is up and running. // // If `KUBECONFIG` is already deinfed in the env then it will do nothing. func (m *KindIntegrationTestStep) Setup(env map[string]string) error { envVars := []string{"KUBECONFIG", "KUBE_CONFIG"} for _, envVar := range envVars { exists := envKubeConfigExists(env, envVar) if exists { return nil } } _, err := exec.LookPath("kind") if err != nil { if mg.Verbose() { fmt.Println("Skipping kind setup; kind command missing") } return nil } clusterName := kubernetesClusterName() stdOut := io.Discard stdErr := io.Discard if mg.Verbose() { stdOut = os.Stdout stdErr = os.Stderr } kubeCfgDir := filepath.Join("build", "kind", clusterName) kubeCfgDir, err = filepath.Abs(kubeCfgDir) if err != nil { return err } kubeConfig := filepath.Join(kubeCfgDir, "kubecfg") if mg.Verbose() { fmt.Println("Kubeconfig: ", kubeConfig) } if err := os.MkdirAll(kubeCfgDir, os.ModePerm); err != nil { return err } args := []string{ "create", "cluster", "--name", clusterName, "--kubeconfig", kubeConfig, "--wait", "300s", } kubeVersion := os.Getenv("K8S_VERSION") if kubeVersion != "" { args = append(args, "--image", fmt.Sprintf("kindest/node:%s", kubeVersion)) } _, err = sh.Exec( map[string]string{}, stdOut, stdErr, "kind", args..., ) if err != nil { return err } env["KUBECONFIG"] = kubeConfig env["KIND_CLUSTER"] = clusterName return nil } // Teardown destroys the kubernetes cluster. func (m *KindIntegrationTestStep) Teardown(env map[string]string) error { stdOut := io.Discard stdErr := io.Discard if mg.Verbose() { stdOut = os.Stdout stdErr = os.Stderr } name, created := env["KIND_CLUSTER"] _, keepUp := os.LookupEnv("KIND_SKIP_DELETE") if created && !keepUp { _, err := sh.Exec( env, stdOut, stdErr, "kind", "delete", "cluster", "--name", name, ) if err != nil { return err } delete(env, "KIND_CLUSTER") } return nil } func envKubeConfigExists(env map[string]string, envVar string) bool { _, exists := env[envVar] if exists { if mg.Verbose() { fmt.Printf("%s: %s\n", envVar, env[envVar]) } if _, err := os.Stat(env[envVar]); err == nil { return true } else if os.IsNotExist(err) { if mg.Verbose() { fmt.Printf("%s file not found: %s: %v\n", envVar, env[envVar], err) } } } return false }