diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 49742ad527..3b0e7ad854 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -1,3 +1,4 @@ +# TODO: right now the release is not fully automated, but the tests below must pass before a release is made manually. See RELEASE.md for more information. name: release on: @@ -7,7 +8,7 @@ on: - 'next' jobs: - latest-tests: + test-current-kubernetes: runs-on: ubuntu-latest strategy: matrix: @@ -38,13 +39,14 @@ jobs: - name: Kubernetes ${{ matrix.kubernetes_version }} ${{ matrix.dbmode }} Integration Tests run: KONG_CLUSTER_VERSION=${{ matrix.kubernetes_version }} make test.integration.${{ matrix.dbmode }} - legacy-tests: + test-previous-kubernetes: + environment: gcloud runs-on: ubuntu-latest strategy: matrix: - kubernetes-version: - - 'v1.19.11' - - 'v1.20.7' + minor: + - '19' + - '20' dbmode: - 'dbless' - 'postgres' @@ -67,7 +69,13 @@ jobs: with: fetch-depth: 0 - - name: Kubernetes ${{ matrix.kubernetes_version }} ${{ matrix.dbmode }} Integration Tests - run: KONG_CLUSTER_VERSION=${{ matrix.kubernetes_version }} make test.integration.${{ matrix.dbmode }} + - name: test ${{ matrix.dbmode }} on GKE v1.${{ matrix.minor }} + run: ./hack/e2e/run.sh + env: + KUBERNETES_MAJOR_VERSION: 1 + KUBERNETES_MINOR_VERSION: ${{ matrix.minor }} + GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} + GOOGLE_PROJECT: ${{ secrets.GOOGLE_PROJECT }} + GOOGLE_LOCATION: ${{ secrets.GOOGLE_LOCATION }} - # TODO: right now the release is not fully automated, but the above tests must pass before a release is made manually. See RELEASE.md for more information. +# TODO: need kubernetes latest job (test against v1.20.7 and v1.21.2): https://github.com/Kong/kubernetes-ingress-controller/issues/1616 diff --git a/hack/e2e/main.go b/hack/e2e/main.go new file mode 100644 index 0000000000..da47f5bb45 --- /dev/null +++ b/hack/e2e/main.go @@ -0,0 +1,94 @@ +package main + +// TODO: this is temporary: it was created for speed but will be replaced +// by upstream functionality in KTF. +// See: https://github.com/Kong/kubernetes-testing-framework/issues/61 + +import ( + "context" + "fmt" + "os" + "strconv" + + "github.com/kong/kubernetes-testing-framework/pkg/clusters" + "github.com/kong/kubernetes-testing-framework/pkg/clusters/types/gke" +) + +const ( + k8sNameVar = "KUBERNETES_CLUSTER_NAME" + k8sMajorVar = "KUBERNETES_MAJOR_VERSION" + k8sMinorVar = "KUBERNETES_MINOR_VERSION" +) + +var ( + ctx = context.Background() + cluster clusters.Cluster + + gkeCreds = os.Getenv(gke.GKECredsVar) + gkeProject = os.Getenv(gke.GKEProjectVar) + gkeLocation = os.Getenv(gke.GKELocationVar) + k8sName = os.Getenv(k8sNameVar) + k8sMajor = os.Getenv(k8sMajorVar) + k8sMinor = os.Getenv(k8sMinorVar) +) + +func main() { + fmt.Println("INFO: configuring GKE cloud environment for tests") + mustNotBeEmpty(gke.GKECredsVar, gkeCreds) + mustNotBeEmpty(gke.GKEProjectVar, gkeProject) + mustNotBeEmpty(gke.GKELocationVar, gkeLocation) + mustNotBeEmpty(k8sNameVar, k8sName) + mustNotBeEmpty(k8sMajorVar, k8sMajor) + mustNotBeEmpty(k8sMinorVar, k8sMinor) + + fmt.Println("INFO: validating cluster version requirements") + major, err := strconv.Atoi(k8sMajor) + mustNotError(err) + minor, err := strconv.Atoi(k8sMinor) + mustNotError(err) + + if len(os.Args) > 1 && os.Args[1] == "cleanup" { + fmt.Printf("INFO: cleanup called, deleting GKE cluster %s\n", k8sName) + cluster, err := gke.NewFromExistingWithEnv(ctx, k8sName) + mustNotError(err) + mustNotError(cluster.Cleanup(ctx)) + fmt.Printf("INFO: GKE cluster %s successfully cleaned up\n", k8sName) + os.Exit(0) + } + + fmt.Printf("INFO: configuring the GKE cluster NAME=(%s) VERSION=(v%d.%d) PROJECT=(%s) LOCATION=(%s)\n", k8sName, major, minor, gkeProject, gkeLocation) + builder := gke.NewBuilder([]byte(gkeCreds), gkeProject, gkeLocation).WithName(k8sName) + builder.WithClusterMinorVersion(uint64(major), uint64(minor)) + + fmt.Printf("INFO: building cluster %s (this can take some time)\n", builder.Name) + cluster, err = builder.Build(ctx) + mustNotError(err) + + fmt.Println("INFO: verifying that the cluster can be communicated with") + version, err := cluster.Client().ServerVersion() + mustNotError(err) + + fmt.Printf("INFO: server version found: %s\n", version) +} + +func mustNotBeEmpty(name, value string) { + if value == "" { + if cluster != nil { + if err := cluster.Cleanup(ctx); err != nil { + panic(fmt.Sprintf("%s was empty, and then cleanup failed: %s", name, err)) + } + } + panic(fmt.Sprintf("%s was empty", name)) + } +} + +func mustNotError(err error) { + if err != nil { + if cluster != nil { + if cleanupErr := cluster.Cleanup(ctx); cleanupErr != nil { + panic(fmt.Sprintf("deployment failed with %s, and then cleanup failed: %s", err, cleanupErr)) + } + } + panic(fmt.Errorf("failed to deploy e2e environment: %w", err)) + } +} diff --git a/hack/e2e/run.sh b/hack/e2e/run.sh new file mode 100755 index 0000000000..5ddb63702a --- /dev/null +++ b/hack/e2e/run.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# TODO: for now our e2e tests are effectively just our integration tests run +# against a conformant, production grade cluster. In the future we will +# add a dedicated e2e test suite. +# +# See: https://github.com/Kong/kubernetes-ingress-controller/issues/1605 + +set -euo pipefail + +WORKDIR="$(dirname "${BASH_SOURCE}")/../.." +cd "${WORKDIR}" + +CLUSTER_NAME="e2e-$(uuidgen)" +KUBERNETES_CLUSTER_NAME="${CLUSTER_NAME}" go run hack/e2e/main.go + +function cleanup() { + KUBERNETES_CLUSTER_NAME="${CLUSTER_NAME}" go run hack/e2e/main.go cleanup +} +trap cleanup EXIT SIGINT SIGQUIT + +GOFLAGS="-tags=integration_tests" KONG_TEST_CLUSTER="gke:${CLUSTER_NAME}" go test -count 1 -timeout 45m -v ./test/integration/...