github.com/solo-io/gloo-mesh-enterprise-helm@v0.5.3-0.20210325185951-12ad0fc5f576/test/e2e/istio/istio_e2e_suite_test.go (about)

     1  package istio_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/solo-io/gloo-mesh-enterprise-helm/test/e2e/istio/pkg"
     7  	"github.com/solo-io/gloo-mesh/test/extensions"
     8  	"io"
     9  	"log"
    10  	"os"
    11  	"os/exec"
    12  	"path/filepath"
    13  	"runtime"
    14  	"strings"
    15  	"testing"
    16  
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/gomega"
    19  	"github.com/rotisserie/eris"
    20  	extendertests "github.com/solo-io/gloo-mesh-enterprise/enterprise-extender/test/e2e/istio/pkg/tests"
    21  	rbactests "github.com/solo-io/gloo-mesh-enterprise/rbac-webhook/test/e2e/pkg/tests"
    22  	coretests "github.com/solo-io/gloo-mesh/test/e2e/istio/pkg/tests"
    23  	"github.com/solo-io/gloo-mesh/test/utils"
    24  	"github.com/solo-io/go-utils/testutils"
    25  	"github.com/solo-io/skv2/codegen/util"
    26  )
    27  
    28  var moduleRoot = util.GetModuleRoot()
    29  
    30  // to skip testing this package, run `make run-tests SKIP_PACKAGES=test/e2e/istio
    31  // to test only this package, run `make run-tests TEST_PKG=test/e2e/istio
    32  func TestIstio(t *testing.T) {
    33  	if os.Getenv("RUN_E2E") == "" {
    34  		fmt.Println("skipping E2E tests")
    35  		return
    36  	}
    37  	RegisterFailHandler(func(message string, callerSkip ...int) {
    38  		log.Printf("Failed with message: %v", message)
    39  		utils.RunShell(util.GetModuleRoot() + "/ci/print-kind-info.sh")
    40  		Fail(message, callerSkip...)
    41  	})
    42  	RunSpecs(t, "E2e Suite")
    43  }
    44  
    45  // Before running tests, federate the two clusters by creating a VirtualMesh with mTLS enabled.
    46  var _ = BeforeSuite(func() {
    47  	ensureWorkingDirectory()
    48  	coretests.SetupClustersAndFederation(deployAndRegisterEnterprise)
    49  })
    50  
    51  func ensureWorkingDirectory() {
    52  	// ensure we are in proper directory
    53  	currentFile, err := testutils.GetCurrentFile()
    54  	Expect(err).NotTo(HaveOccurred())
    55  	currentDir := filepath.Dir(currentFile)
    56  	utils.TestManifestDir = currentDir
    57  	projectRoot := filepath.Join(currentDir, "..", "..", "..")
    58  	err = os.Chdir(projectRoot)
    59  	Expect(err).NotTo(HaveOccurred())
    60  }
    61  
    62  var _ = AfterSuite(func() {
    63  	coretests.TeardownFederationAndClusters()
    64  })
    65  
    66  // initialize all tests
    67  var _ = allTests()
    68  
    69  func allTests() bool {
    70  	/*
    71  		test order matters here:
    72  		- we run extender tests first because coretests modify settings (extender)
    73  		- we run rbac tests last as rbactests modify rbac
    74  	*/
    75  	return Describe("enterprise helm chart", func() {
    76  		extendertests.InitializeTests()
    77  		coretests.InitializeTests()
    78  		rbactests.InitializeTests()
    79  	})
    80  }
    81  
    82  func deployAndRegisterEnterprise() {
    83  	// override Docker Host Addr for CircleCI
    84  	extensions.DockerHostAddress = pkg.DockerHostAddress
    85  
    86  	err := installEnterpriseChart()
    87  	Expect(err).NotTo(HaveOccurred())
    88  	err = registerCluster("mgmt-cluster")
    89  	Expect(err).NotTo(HaveOccurred())
    90  	err = registerCluster("remote-cluster")
    91  	Expect(err).NotTo(HaveOccurred())
    92  
    93  	err = applyCustomBootstrapPatch("remote-cluster", "bookinfo", "reviews-v3")
    94  	Expect(err).NotTo(HaveOccurred())
    95  }
    96  
    97  func installEnterpriseChart() error {
    98  	chartPath := os.Getenv("OUTPUT_CHART_PATH")
    99  	if chartPath == "" {
   100  		if err := runCommand("make", "package-chart"); err != nil {
   101  			return err
   102  		}
   103  		path, err := runCommandOut("make", "print-chart-path")
   104  		if err != nil {
   105  			return err
   106  		}
   107  		chartPath = path
   108  	}
   109  	licenseKey := os.Getenv("LICENSE_KEY")
   110  	if chartPath == "" {
   111  		return eris.Errorf("must provide var LICENSE_KEY with valid enterprise license key")
   112  	}
   113  
   114  	if err := runCommand(
   115  		"kubectl",
   116  		"create",
   117  		"ns",
   118  		"gloo-mesh",
   119  	); err != nil && !strings.Contains(err.Error(), `namespaces "gloo-mesh" already exists`) {
   120  		return err
   121  	}
   122  
   123  	if err := runCommand(
   124  		"helm",
   125  		"upgrade",
   126  		"--install",
   127  		"--namespace=gloo-mesh",
   128  		"gloo-mesh-enterprise",
   129  		chartPath,
   130  		"--set",
   131  		"licenseKey="+licenseKey,
   132  		"--set",
   133  		"gloo-mesh-ui.enabled=false", // disable apiserver/UI to free up compute for CI
   134  	); err != nil {
   135  		return err
   136  	}
   137  
   138  	for _, deployment := range []string{
   139  		"discovery",
   140  		"networking",
   141  		"enterprise-extender",
   142  		"rbac-webhook",
   143  	} {
   144  		if err := runCommand(
   145  			"kubectl",
   146  			"rollout",
   147  			"status",
   148  			"-n=gloo-mesh",
   149  			"deployment",
   150  			deployment,
   151  		); err != nil {
   152  			return err
   153  		}
   154  	}
   155  
   156  	return nil
   157  }
   158  
   159  // uses meshctl from path to register cluster;
   160  // make sure meshctl version matches gloo-mesh version from chart
   161  func registerCluster(cluster string) error {
   162  	apiServerAddr, err := getApiserverAddress(cluster)
   163  	if err != nil {
   164  		return err
   165  	}
   166  	if err := runCommand(
   167  		"meshctl",
   168  		"cluster",
   169  		"register",
   170  		"--mgmt-context=kind-mgmt-cluster",
   171  		"--cluster-name="+cluster,
   172  		"--remote-context=kind-"+cluster,
   173  		"--api-server-address="+apiServerAddr,
   174  		"--install-wasm-agent",
   175  		// TODO joekelley remove this line when we release enterprise-networking
   176  		"--wasm-agent-chart-file=https://storage.googleapis.com/gloo-mesh-enterprise/wasm-agent/wasm-agent-"+"0.5.0"+".tgz",
   177  	); err != nil {
   178  		return err
   179  	}
   180  
   181  	return nil
   182  }
   183  
   184  func getApiserverAddress(cluster string) (string, error) {
   185  	switch runtime.GOOS {
   186  	case "darwin":
   187  		return "host.docker.internal", nil
   188  	default:
   189  		addr, err := runCommandOut("bash", "-c", `docker exec `+cluster+`-control-plane ip addr show dev eth0 | sed -nE 's|\s*inet\s+([0-9.]+).*|\1|p'`)
   190  		if err != nil {
   191  			return "", err
   192  		}
   193  		return strings.TrimSpace(addr) + ":6443", nil
   194  	}
   195  }
   196  
   197  func applyCustomBootstrapPatch(clusterName, namespace, deploymentName string) error {
   198  	if _, err := runCommandInOut(
   199  		"kubectl",
   200  		pkg.CustomBootsrapConfigmap(namespace),
   201  		"--context=kind-"+clusterName,
   202  		"apply",
   203  		"-f-",
   204  	); err != nil {
   205  		return err
   206  	}
   207  
   208  	if err := runCommand(
   209  		"kubectl",
   210  		"patch",
   211  		"deployment",
   212  		"-n", namespace,
   213  		deploymentName,
   214  		"--context=kind-"+clusterName,
   215  		fmt.Sprintf("--patch=%v", pkg.CustomBootstrapOverridePatch),
   216  	); err != nil {
   217  		return err
   218  	}
   219  
   220  	return nil
   221  }
   222  
   223  func runCommand(name string, args ...string) error {
   224  	_, err := runCommandOut(name, args...)
   225  	return err
   226  }
   227  
   228  // always runs command from module root
   229  func runCommandOut(name string, args ...string) (string, error) {
   230  	return runCommandInOut(name, "", args...)
   231  }
   232  
   233  // always runs command from module root
   234  func runCommandInOut(name, stdin string, args ...string) (string, error) {
   235  	out := &bytes.Buffer{}
   236  
   237  	cmd := exec.Command(
   238  		name,
   239  		args...,
   240  	)
   241  	if stdin != "" {
   242  		cmd.Stdin = bytes.NewBuffer([]byte(stdin))
   243  	}
   244  	cmd.Stdout = io.MultiWriter(out, GinkgoWriter)
   245  	cmd.Stderr = io.MultiWriter(out, GinkgoWriter)
   246  	cmd.Dir = moduleRoot
   247  
   248  	fullCommand := append([]string{name}, args...)
   249  	for _, arg := range args {
   250  		if len(arg) > 64 {
   251  			// silence license key in logs
   252  			arg = arg[:64] + "..."
   253  		}
   254  	}
   255  
   256  	log.Printf("running command %v", fullCommand)
   257  
   258  	if err := cmd.Run(); err != nil {
   259  		return "", eris.Wrapf(err, "running command (%v) failed: %v",
   260  			fullCommand,
   261  			out.String())
   262  	}
   263  	return out.String(), nil
   264  }