From 57fef1fc81f5620c9518a1a6bc082a4ff4342213 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Wed, 7 Jun 2023 22:51:02 -0400 Subject: [PATCH 001/120] Add bug to changelog so that go-changelog works (#2276) --- .changelog/2194.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changelog/2194.txt b/.changelog/2194.txt index 997326218b..fb265d9739 100644 --- a/.changelog/2194.txt +++ b/.changelog/2194.txt @@ -1,3 +1,3 @@ -```release-note: +```release-note:bug crd: fix bug on service intentions CRD causing some updates to be ignored. ``` From e35eaa3cf48fb0264269b65ca196e1ed2792aee4 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Thu, 8 Jun 2023 12:14:35 -0400 Subject: [PATCH 002/120] Fix retry loops that use `t` (#2311) --- acceptance/tests/cli/cli_install_test.go | 2 +- .../config_entries_namespaces_test.go | 58 +++++++++---------- .../config-entries/config_entries_test.go | 58 +++++++++---------- .../create-federation-secret/command_test.go | 6 +- 4 files changed, 62 insertions(+), 62 deletions(-) diff --git a/acceptance/tests/cli/cli_install_test.go b/acceptance/tests/cli/cli_install_test.go index 009d3140fc..bb497f913f 100644 --- a/acceptance/tests/cli/cli_install_test.go +++ b/acceptance/tests/cli/cli_install_test.go @@ -74,7 +74,7 @@ func TestInstall(t *testing.T) { retry.RunWith(retrier, t, func(r *retry.R) { for podName := range list { out, err := cli.Run(t, ctx.KubectlOptions(t), "proxy", "read", podName) - require.NoError(t, err) + require.NoError(r, err) output := string(out) logger.Log(t, output) diff --git a/acceptance/tests/config-entries/config_entries_namespaces_test.go b/acceptance/tests/config-entries/config_entries_namespaces_test.go index ced7cc8236..91d0c69df4 100644 --- a/acceptance/tests/config-entries/config_entries_namespaces_test.go +++ b/acceptance/tests/config-entries/config_entries_namespaces_test.go @@ -242,35 +242,35 @@ func TestControllerNamespaces(t *testing.T) { require.NoError(r, err) rateLimitIPConfigEntry, ok := entry.(*api.RateLimitIPConfigEntry) require.True(r, ok, "could not cast to RateLimitIPConfigEntry") - require.Equal(t, "permissive", rateLimitIPConfigEntry.Mode) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ACL.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ACL.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Catalog.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Catalog.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ConfigEntry.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ConfigEntry.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ConnectCA.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ConnectCA.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Coordinate.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Coordinate.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.DiscoveryChain.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.DiscoveryChain.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Health.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Health.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Intention.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Intention.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.KV.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.KV.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Tenancy.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Tenancy.WriteRate) - //require.Equal(t, 100.0, rateLimitIPConfigEntry.PreparedQuery.ReadRate) - //require.Equal(t, 100.0, rateLimitIPConfigEntry.PreparedQuery.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Session.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Session.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Txn.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Txn.WriteRate) + require.Equal(r, "permissive", rateLimitIPConfigEntry.Mode) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ACL.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ACL.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Catalog.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Catalog.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ConfigEntry.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ConfigEntry.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ConnectCA.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ConnectCA.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Coordinate.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Coordinate.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.DiscoveryChain.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.DiscoveryChain.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Health.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Health.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Intention.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Intention.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.KV.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.KV.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Tenancy.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Tenancy.WriteRate) + //require.Equal(r, 100.0, rateLimitIPConfigEntry.PreparedQuery.ReadRate) + //require.Equal(r, 100.0, rateLimitIPConfigEntry.PreparedQuery.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Session.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Session.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Txn.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Txn.WriteRate) }) } diff --git a/acceptance/tests/config-entries/config_entries_test.go b/acceptance/tests/config-entries/config_entries_test.go index 089f96767f..e37e3d6c7f 100644 --- a/acceptance/tests/config-entries/config_entries_test.go +++ b/acceptance/tests/config-entries/config_entries_test.go @@ -209,35 +209,35 @@ func TestController(t *testing.T) { require.NoError(r, err) rateLimitIPConfigEntry, ok := entry.(*api.RateLimitIPConfigEntry) require.True(r, ok, "could not cast to RateLimitIPConfigEntry") - require.Equal(t, "permissive", rateLimitIPConfigEntry.Mode) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ACL.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ACL.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Catalog.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Catalog.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ConfigEntry.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ConfigEntry.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ConnectCA.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.ConnectCA.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Coordinate.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Coordinate.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.DiscoveryChain.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.DiscoveryChain.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Health.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Health.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Intention.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Intention.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.KV.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.KV.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Tenancy.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Tenancy.WriteRate) - //require.Equal(t, 100.0, rateLimitIPConfigEntry.PreparedQuery.ReadRate) - //require.Equal(t, 100.0, rateLimitIPConfigEntry.PreparedQuery.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Session.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Session.WriteRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Txn.ReadRate) - require.Equal(t, 100.0, rateLimitIPConfigEntry.Txn.WriteRate, 100.0) + require.Equal(r, "permissive", rateLimitIPConfigEntry.Mode) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ACL.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ACL.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Catalog.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Catalog.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ConfigEntry.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ConfigEntry.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ConnectCA.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.ConnectCA.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Coordinate.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Coordinate.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.DiscoveryChain.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.DiscoveryChain.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Health.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Health.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Intention.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Intention.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.KV.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.KV.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Tenancy.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Tenancy.WriteRate) + //require.Equal(r, 100.0, rateLimitIPConfigEntry.PreparedQuery.ReadRate) + //require.Equal(r, 100.0, rateLimitIPConfigEntry.PreparedQuery.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Session.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Session.WriteRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Txn.ReadRate) + require.Equal(r, 100.0, rateLimitIPConfigEntry.Txn.WriteRate) }) } diff --git a/control-plane/subcommand/create-federation-secret/command_test.go b/control-plane/subcommand/create-federation-secret/command_test.go index 16939a2868..15f12b132c 100644 --- a/control-plane/subcommand/create-federation-secret/command_test.go +++ b/control-plane/subcommand/create-federation-secret/command_test.go @@ -528,7 +528,7 @@ func TestRun_WaitsForMeshGatewayInstances(t *testing.T) { CAFile: caFile, }, }) - require.NoError(t, err) + require.NoError(r, err) }) err = client.Agent().ServiceRegister(&api.AgentServiceRegistration{ @@ -825,7 +825,7 @@ func TestRun_ReplicationSecretDelay(t *testing.T) { }, }, metav1.CreateOptions{}) - require.NoError(t, err) + require.NoError(r, err) }) }() @@ -1005,7 +1005,7 @@ func TestRun_ConsulClientDelay(t *testing.T) { Server: randomPorts[5], } }) - require.NoError(t, err) + require.NoError(r, err) }) // Construct Consul client. From f4435acf0020c1f6bda25f875660055116ef155a Mon Sep 17 00:00:00 2001 From: skpratt Date: Thu, 8 Jun 2023 13:28:55 -0500 Subject: [PATCH 003/120] Add FIPS builds (#2165) * Add FIPS builds for linux amd64 * add version check * fix CI labels and add local dev commands * fix ci version tagging * switch to ubuntu 20.04 * add CLI version tag * add gcompat for alpine glibc cgo compatibility * remove FIPS version check from connect-init * address comments --- .github/workflows/build.yml | 92 +++++++++++++------ Makefile | 15 +++ cli/version/fips_build.go | 27 ++++++ cli/version/non_fips_build.go | 12 +++ cli/version/version.go | 6 +- control-plane/Dockerfile | 6 +- .../build-support/functions/20-build.sh | 14 ++- .../build-support/scripts/build-local.sh | 7 ++ .../subcommand/connect-init/command.go | 23 ++++- control-plane/version/fips_build.go | 27 ++++++ control-plane/version/non_fips_build.go | 12 +++ control-plane/version/version.go | 6 +- 12 files changed, 210 insertions(+), 37 deletions(-) create mode 100644 cli/version/fips_build.go create mode 100644 cli/version/non_fips_build.go create mode 100644 control-plane/version/fips_build.go create mode 100644 control-plane/version/non_fips_build.go diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52f94ec71c..8eef629401 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -64,7 +64,7 @@ jobs: build: needs: [get-go-version, get-product-version] - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 # the GLIBC is too high on 22.04 strategy: matrix: include: @@ -79,20 +79,28 @@ jobs: - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s" } - # control-plane + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } + + # control-plane - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "freebsd", goarch: "386", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "freebsd", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "386", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - # solaris is only built for the control plane + # solaris is only built for the control plane - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "solaris", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "386", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - # consul-cni + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } + + # consul-cni - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "freebsd", goarch: "386", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "freebsd", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "386", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } @@ -104,10 +112,14 @@ jobs: - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } + fail-fast: true - name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} ${{ matrix.component }} build + name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} ${{ matrix.component }} ${{ matrix.fips }} build steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 @@ -116,6 +128,25 @@ jobs: with: go-version: ${{ matrix.go }} + - name: Replace Go for Windows FIPS with Microsoft Go + if: ${{ matrix.fips == '.fips1402' && matrix.goos == 'windows' }} + run: | + # Uninstall standard Go and use microsoft/go instead + rm -rf /home/runner/actions-runner/_work/_tool/go + curl https://aka.ms/golang/release/latest/go${{ matrix.go }}-1.linux-amd64.tar.gz -Lo go${{ matrix.go }}.linux-amd64.tar.gz + tar -C $HOME -xf go${{ matrix.go }}.linux-amd64.tar.gz + chmod +x $HOME/go/bin + export PATH=$HOME/go/bin:$PATH + if [ $(which go) != "$HOME/go/bin/go" ]; then + echo "Unable to verify microsoft/go toolchain" + exit 1 + fi + + - name: Install cross-compiler for FIPS on arm + if: ${{ matrix.fips == '.fips1402' && matrix.goarch == 'arm64' }} + run: | + sudo apt-get update --allow-releaseinfo-change-suite --allow-releaseinfo-change-version && sudo apt-get install -y gcc-aarch64-linux-gnu + - name: Build env: GOOS: ${{ matrix.goos }} @@ -130,14 +161,14 @@ jobs: export GIT_IMPORT=github.com/hashicorp/consul-k8s/${{ matrix.component }}/version export GOLDFLAGS="-X ${GIT_IMPORT}.GitCommit=${GIT_COMMIT}${GIT_DIRTY} -X ${GIT_IMPORT}.GitDescribe=${{ needs.get-product-version.outputs.product-version }}" - CGO_ENABLED=0 go build -o dist/${{ matrix.bin_name }} -ldflags "${GOLDFLAGS}" . - zip -r -j out/${{ matrix.pkg_name }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/ + ${{ matrix.env }} go build -o dist/${{ matrix.bin_name }} -ldflags "${GOLDFLAGS}" -tags=${{ matrix.gotags }} . + zip -r -j out/${{ matrix.pkg_name }}_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip dist/ - name: Upload built binaries uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 with: - name: ${{ matrix.pkg_name }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip - path: ${{ matrix.component}}/out/${{ matrix.pkg_name }}_${{ needs.get-product-version.outputs.product-version }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + name: ${{ matrix.pkg_name }}_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip + path: ${{ matrix.component}}/out/${{ matrix.pkg_name }}_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_${{ matrix.goos }}_${{ matrix.goarch }}.zip - name: Package rpm and deb files if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} @@ -146,7 +177,7 @@ jobs: name: consul-k8s description: "consul-k8s provides a cli interface to first-class integrations between Consul and Kubernetes." arch: ${{ matrix.goarch }} - version: ${{ needs.get-product-version.outputs.product-version }} + version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} maintainer: "HashiCorp" homepage: "https://github.com/hashicorp/consul-k8s" license: "MPL-2.0" @@ -171,7 +202,7 @@ jobs: cd /work rpm -ivh out/${{ env.RPM_PACKAGE }} CONSUL_K8S_VERSION="$(consul-k8s version | awk '{print $2}')" - VERSION="v${{ needs.get-product-version.outputs.product-version }}" + VERSION="v${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}" if [ "${VERSION}" != "${CONSUL_K8S_VERSION}" ]; then echo "Test FAILED, expected: ${VERSION}, got: ${CONSUL_K8S_VERSION}" exit 1 @@ -196,7 +227,7 @@ jobs: cd /work apt install ./out/${{ env.DEB_PACKAGE }} CONSUL_K8S_VERSION="$(consul-k8s version | awk '{print $2}')" - VERSION="v${{ needs.get-product-version.outputs.product-version }}" + VERSION="v${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}" if [ "${VERSION}" != "${CONSUL_K8S_VERSION}" ]; then echo "Test FAILED, expected: ${VERSION}, got: ${CONSUL_K8S_VERSION}" exit 1 @@ -211,24 +242,30 @@ jobs: path: out/${{ env.DEB_PACKAGE }} build-docker: - name: Docker ${{ matrix.arch }} default release build + name: Docker ${{ matrix.goarch }} ${{ matrix.fips }} default release build needs: [get-product-version, build] runs-on: ubuntu-latest strategy: matrix: - arch: ["arm", "arm64", "386", "amd64"] + include: + - { goos: "linux", goarch: "arm" } + - { goos: "linux", goarch: "arm64" } + - { goos: "linux", goarch: "386" } + - { goos: "linux", goarch: "amd64" } + - { goos: "linux", goarch: "amd64", fips: ".fips1402" } + - { goos: "linux", goarch: "arm64", fips: ".fips1402" } env: repo: ${{ github.event.repository.name }} - version: ${{ needs.get-product-version.outputs.product-version }} + version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: - name: consul-cni_${{ needs.get-product-version.outputs.product-version }}_linux_${{ matrix.arch }}.zip - path: control-plane/dist/cni/linux/${{ matrix.arch }} + name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_${{ matrix.goos}}_${{ matrix.goarch }}.zip + path: control-plane/dist/cni/${{ matrix.goos}}/${{ matrix.goarch }} - name: extract consul-cni zip env: - ZIP_LOCATION: control-plane/dist/cni/linux/${{ matrix.arch }} + ZIP_LOCATION: control-plane/dist/cni/${{ matrix.goos}}/${{ matrix.goarch }} run: | cd "${ZIP_LOCATION}" unzip -j *.zip @@ -244,7 +281,7 @@ jobs: echo "Test PASSED" version: ${{ env.version }} target: release-default - arch: ${{ matrix.arch }} + arch: ${{ matrix.goarch }} pkg_name: consul-k8s-control-plane_${{ env.version }} bin_name: consul-k8s-control-plane workdir: control-plane @@ -255,20 +292,22 @@ jobs: docker.io/hashicorppreview/${{ env.repo }}-control-plane:${{ env.version }}-${{ github.sha }} build-docker-ubi-redhat-registry: - name: Docker ${{ matrix.arch }} UBI build for RedHat Registry + name: Docker ${{ matrix.arch }} ${{ matrix.fips }} UBI build for RedHat Registry needs: [get-product-version, build] runs-on: ubuntu-latest strategy: matrix: - arch: ["amd64"] + include: + - { arch: "amd64" } + - { arch: "amd64", fips: ".fips1402" } env: repo: ${{ github.event.repository.name }} - version: ${{ needs.get-product-version.outputs.product-version }} + version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: - name: consul-cni_${{ needs.get-product-version.outputs.product-version }}_linux_${{ matrix.arch }}.zip + name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_linux_${{ matrix.arch }}.zip path: control-plane/dist/cni/linux/${{ matrix.arch }} - name: extract consul-cni zip env: @@ -297,20 +336,21 @@ jobs: redhat_tag: quay.io/redhat-isv-containers/611ca2f89a9b407267837100:${{env.version}}-ubi build-docker-ubi-dockerhub: - name: Docker ${{ matrix.arch }} UBI build for DockerHub + name: Docker ${{ matrix.arch }} ${{ matrix.fips }} UBI build for DockerHub needs: [ get-product-version, build ] runs-on: ubuntu-latest strategy: matrix: arch: [ "amd64" ] + fips: [ ".fips1402", "" ] env: repo: ${{ github.event.repository.name }} - version: ${{ needs.get-product-version.outputs.product-version }} + version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: - name: consul-cni_${{ needs.get-product-version.outputs.product-version }}_linux_${{ matrix.arch }}.zip + name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_linux_${{ matrix.arch }}.zip path: control-plane/dist/cni/linux/${{ matrix.arch }} - name: extract consul-cni zip env: diff --git a/Makefile b/Makefile index 5adfb55657..628b13e2f9 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,17 @@ control-plane-dev-docker-multi-arch: check-remote-dev-image-env ## Build consul- --push \ -f $(CURDIR)/control-plane/Dockerfile $(CURDIR)/control-plane +control-plane-fips-dev-docker: ## Build consul-k8s-control-plane FIPS dev Docker image. + @$(SHELL) $(CURDIR)/control-plane/build-support/scripts/build-local.sh -o linux -a $(GOARCH) --fips + @docker build -t '$(DEV_IMAGE)' \ + --target=dev \ + --build-arg 'TARGETARCH=$(GOARCH)' \ + --build-arg 'GIT_COMMIT=$(GIT_COMMIT)' \ + --build-arg 'GIT_DIRTY=$(GIT_DIRTY)' \ + --build-arg 'GIT_DESCRIBE=$(GIT_DESCRIBE)' \ + --push \ + -f $(CURDIR)/control-plane/Dockerfile $(CURDIR)/control-plane + control-plane-test: ## Run go test for the control plane. cd control-plane; go test ./... @@ -98,6 +109,10 @@ cli-dev: @echo "==> Installing consul-k8s CLI tool for ${GOOS}/${GOARCH}" @cd cli; go build -o ./bin/consul-k8s; cp ./bin/consul-k8s ${GOPATH}/bin/ +cli-fips-dev: + @echo "==> Installing consul-k8s CLI tool for ${GOOS}/${GOARCH}" + @cd cli; CGO_ENABLED=1 GOEXPERIMENT=boringcrypto go build -o ./bin/consul-k8s -tags "fips"; cp ./bin/consul-k8s ${GOPATH}/bin/ + cli-lint: ## Run linter in the control-plane directory. cd cli; golangci-lint run -c ../.golangci.yml diff --git a/cli/version/fips_build.go b/cli/version/fips_build.go new file mode 100644 index 0000000000..4d04cc6539 --- /dev/null +++ b/cli/version/fips_build.go @@ -0,0 +1,27 @@ +//go:build fips + +package version + +// This validates during compilation that we are being built with a FIPS enabled go toolchain +import ( + _ "crypto/tls/fipsonly" + "runtime" + "strings" +) + +// IsFIPS returns true if consul-k8s is operating in FIPS-140-2 mode. +func IsFIPS() bool { + return true +} + +func GetFIPSInfo() string { + str := "Enabled" + // Try to get the crypto module name + gover := strings.Split(runtime.Version(), "X:") + if len(gover) >= 2 { + gover_last := gover[len(gover)-1] + // Able to find crypto module name; add that to status string. + str = "FIPS 140-2 Enabled, crypto module " + gover_last + } + return str +} diff --git a/cli/version/non_fips_build.go b/cli/version/non_fips_build.go new file mode 100644 index 0000000000..f72aecae73 --- /dev/null +++ b/cli/version/non_fips_build.go @@ -0,0 +1,12 @@ +//go:build !fips + +package version + +// IsFIPS returns true if consul-k8s is operating in FIPS-140-2 mode. +func IsFIPS() bool { + return false +} + +func GetFIPSInfo() string { + return "" +} diff --git a/cli/version/version.go b/cli/version/version.go index 81433c0a5f..320600c30b 100644 --- a/cli/version/version.go +++ b/cli/version/version.go @@ -39,8 +39,12 @@ func GetHumanVersion() string { release = "dev" } + if IsFIPS() { + version += ".fips1402" + } + if release != "" { - if !strings.HasSuffix(version, "-"+release) { + if !strings.Contains(version, "-"+release) { // if we tagged a prerelease version then the release is in the version already version += fmt.Sprintf("-%s", release) } diff --git a/control-plane/Dockerfile b/control-plane/Dockerfile index de0c1cf1ff..5b3d73e625 100644 --- a/control-plane/Dockerfile +++ b/control-plane/Dockerfile @@ -92,7 +92,11 @@ LABEL name=${BIN_NAME} \ ENV BIN_NAME=${BIN_NAME} ENV VERSION=${PRODUCT_VERSION} -RUN apk add --no-cache ca-certificates libcap openssl su-exec iputils libc6-compat iptables +RUN apk add --no-cache ca-certificates libcap openssl su-exec iputils gcompat libc6-compat libstdc++ iptables + +# for FIPS CGO glibc compatibility in alpine +# see https://github.com/golang/go/issues/59305 +RUN ln -s /lib/libc.so.6 /usr/lib/libresolv.so.2 # TARGETOS and TARGETARCH are set automatically when --platform is provided. ARG TARGETOS diff --git a/control-plane/build-support/functions/20-build.sh b/control-plane/build-support/functions/20-build.sh index a4f36ee3e4..e9540956c9 100644 --- a/control-plane/build-support/functions/20-build.sh +++ b/control-plane/build-support/functions/20-build.sh @@ -180,7 +180,7 @@ function build_consul_local { # * - error # # Note: - # The GOLDFLAGS and GOTAGS environment variables will be used if set + # The GOLDFLAGS, GOEXPERIMENT, and GOTAGS environment variables will be used if set # If the CONSUL_DEV environment var is truthy only the local platform/architecture is built. # If the XC_OS or the XC_ARCH environment vars are present then only those platforms/architectures # will be built. Otherwise all supported platform/architectures are built @@ -188,6 +188,14 @@ function build_consul_local { # build with go install. # The GOXPARALLEL environment variable is used if set + if [ $GOTAGS == "fips" ]; then + CGO_ENABLED=1 + else + CGO_ENABLED=0 + fi + + echo "GOEXPERIMENT: $GOEXPERIMENT, GOTAGS: $GOTAGS CGO_ENABLED: $CGO_ENABLED" >> ~/debug.txt + if ! test -d "$1" then err "ERROR: '$1' is not a directory. build_consul must be called with the path to the top level source as the first argument'" @@ -242,7 +250,7 @@ function build_consul_local { then status "Using gox for concurrent compilation" - CGO_ENABLED=0 gox \ + CGO_ENABLED=${CGO_ENABLED} GOEXPERIMENT=${GOEXPERIMENT} gox \ -os="${build_os}" \ -arch="${build_arch}" \ -ldflags="${GOLDFLAGS}" \ @@ -290,7 +298,7 @@ function build_consul_local { else OS_BIN_EXTENSION="" fi - CGO_ENABLED=0 GOOS=${os} GOARCH=${arch} go build -ldflags "${GOLDFLAGS}" -tags "${GOTAGS}" -o "${outdir}/${bin_name}" + CGO_ENABLED=${CGO_ENABLED} GOEXPERIMENT=${GOEXPERIMENT} GOOS=${os} GOARCH=${arch} go build -ldflags "${GOLDFLAGS}" -tags "${GOTAGS}" -o "${outdir}/${bin_name}" if test $? -ne 0 then err "ERROR: Failed to build Consul for ${osarch}" diff --git a/control-plane/build-support/scripts/build-local.sh b/control-plane/build-support/scripts/build-local.sh index 453310b0b7..7325e025b7 100755 --- a/control-plane/build-support/scripts/build-local.sh +++ b/control-plane/build-support/scripts/build-local.sh @@ -35,6 +35,8 @@ Options: -a | --arch ARCH Space separated string of architectures to build. + --fips FIPS Whether to use FIPS cryptography. + -h | --help Print this help text. EOF } @@ -94,6 +96,11 @@ function main { build_arch="$2" shift 2 ;; + --fips ) + GOTAGS="fips" + GOEXPERIMENT="boringcrypto" + shift 1 + ;; * ) err_usage "ERROR: Unknown argument: '$1'" return 1 diff --git a/control-plane/subcommand/connect-init/command.go b/control-plane/subcommand/connect-init/command.go index 72090d299b..4f83ea98f1 100644 --- a/control-plane/subcommand/connect-init/command.go +++ b/control-plane/subcommand/connect-init/command.go @@ -17,17 +17,19 @@ import ( "time" "github.com/cenkalti/backoff" - "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" - "github.com/hashicorp/consul-k8s/control-plane/consul" - "github.com/hashicorp/consul-k8s/control-plane/namespaces" - "github.com/hashicorp/consul-k8s/control-plane/subcommand/common" - "github.com/hashicorp/consul-k8s/control-plane/subcommand/flags" "github.com/hashicorp/consul-server-connection-manager/discovery" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/iptables" "github.com/hashicorp/go-hclog" "github.com/mitchellh/cli" "github.com/mitchellh/mapstructure" + + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" + "github.com/hashicorp/consul-k8s/control-plane/consul" + "github.com/hashicorp/consul-k8s/control-plane/namespaces" + "github.com/hashicorp/consul-k8s/control-plane/subcommand/common" + "github.com/hashicorp/consul-k8s/control-plane/subcommand/flags" + "github.com/hashicorp/consul-k8s/control-plane/version" ) const ( @@ -161,6 +163,17 @@ func (c *Command) Run(args []string) int { c.logger.Error("Unable to get client connection", "error", err) return 1 } + if version.IsFIPS() { + // make sure we are also using FIPS Consul + var versionInfo map[string]interface{} + _, err := consulClient.Raw().Query("/v1/agent/version", versionInfo, nil) + if err != nil { + c.logger.Warn("This is a FIPS build of consul-k8s, which should be used with FIPS Consul. Unable to verify FIPS Consul while setting up Consul API client.") + } + if val, ok := versionInfo["FIPS"]; !ok || val == "" { + c.logger.Warn("This is a FIPS build of consul-k8s, which should be used with FIPS Consul. A non-FIPS version of Consul was detected.") + } + } proxyService := &api.AgentService{} if c.flagGatewayKind != "" { err = backoff.Retry(c.getGatewayRegistration(consulClient), backoff.WithMaxRetries(backoff.NewConstantBackOff(1*time.Second), c.serviceRegistrationPollingAttempts)) diff --git a/control-plane/version/fips_build.go b/control-plane/version/fips_build.go new file mode 100644 index 0000000000..4d04cc6539 --- /dev/null +++ b/control-plane/version/fips_build.go @@ -0,0 +1,27 @@ +//go:build fips + +package version + +// This validates during compilation that we are being built with a FIPS enabled go toolchain +import ( + _ "crypto/tls/fipsonly" + "runtime" + "strings" +) + +// IsFIPS returns true if consul-k8s is operating in FIPS-140-2 mode. +func IsFIPS() bool { + return true +} + +func GetFIPSInfo() string { + str := "Enabled" + // Try to get the crypto module name + gover := strings.Split(runtime.Version(), "X:") + if len(gover) >= 2 { + gover_last := gover[len(gover)-1] + // Able to find crypto module name; add that to status string. + str = "FIPS 140-2 Enabled, crypto module " + gover_last + } + return str +} diff --git a/control-plane/version/non_fips_build.go b/control-plane/version/non_fips_build.go new file mode 100644 index 0000000000..f72aecae73 --- /dev/null +++ b/control-plane/version/non_fips_build.go @@ -0,0 +1,12 @@ +//go:build !fips + +package version + +// IsFIPS returns true if consul-k8s is operating in FIPS-140-2 mode. +func IsFIPS() bool { + return false +} + +func GetFIPSInfo() string { + return "" +} diff --git a/control-plane/version/version.go b/control-plane/version/version.go index 81433c0a5f..320600c30b 100644 --- a/control-plane/version/version.go +++ b/control-plane/version/version.go @@ -39,8 +39,12 @@ func GetHumanVersion() string { release = "dev" } + if IsFIPS() { + version += ".fips1402" + } + if release != "" { - if !strings.HasSuffix(version, "-"+release) { + if !strings.Contains(version, "-"+release) { // if we tagged a prerelease version then the release is in the version already version += fmt.Sprintf("-%s", release) } From 097f94550903f6ab41e14e7a47a0f12f97cfeee3 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Thu, 8 Jun 2023 12:56:03 -0700 Subject: [PATCH 004/120] activated weekly acceptance tests for 1-2-x (#2315) - making this trigger nightly until after 1.2.0 GA - leaving 0.49.x active until after 1.2.0 GA --- .github/workflows/weekly-acceptance-1-2-x.yml | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/weekly-acceptance-1-2-x.yml diff --git a/.github/workflows/weekly-acceptance-1-2-x.yml b/.github/workflows/weekly-acceptance-1-2-x.yml new file mode 100644 index 0000000000..353a086f16 --- /dev/null +++ b/.github/workflows/weekly-acceptance-1-2-x.yml @@ -0,0 +1,30 @@ +# Dispatch to the consul-k8s-workflows with a weekly cron +# +# A separate file is needed for each release because the cron schedules are different for each release. +name: weekly-acceptance-1-2-x +on: + schedule: + # * is a special character in YAML so you have to quote this string + # Run weekly on Wednesday at 3AM UTC/11PM EST/8PM PST + # - cron: '0 3 * * 3' + - cron: '0 0 * * *' # Temporarily nightly until 1.2.0 GA + + +# these should be the only settings that you will ever need to change +env: + BRANCH: "release/1.2.x" + CONTEXT: "weekly" + +jobs: + cloud: + name: cloud + runs-on: ubuntu-latest + steps: + - uses: benc-uk/workflow-dispatch@798e70c97009500150087d30d9f11c5444830385 # v1.2.2 + name: cloud + with: + workflow: cloud.yml + repo: hashicorp/consul-k8s-workflows + ref: main + token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} + inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' From 61c72805622502bd13e461457a03acec40b2d1b2 Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Thu, 8 Jun 2023 23:30:46 -0400 Subject: [PATCH 005/120] Net 4230/add tcp to basic acceptance test (#2297) * first run through, needs help * still need to make secure pass * left something uncommented * it works and also cleanup * fix acceptance tests --- acceptance/go.mod | 10 -- acceptance/go.sum | 17 ---- .../api-gateway/api_gateway_tenancy_test.go | 2 +- .../tests/api-gateway/api_gateway_test.go | 95 +++++++++++++++++-- .../anyuid-scc-rolebinding.yaml | 14 +++ .../bases/static-server-tcp/deployment.yaml | 49 ++++++++++ .../static-server-tcp/kustomization.yaml | 11 +++ .../privileged-scc-rolebinding.yaml | 14 +++ .../static-server-tcp/psp-rolebinding.yaml | 14 +++ .../bases/static-server-tcp/service.yaml | 15 +++ .../static-server-tcp/serviceaccount.yaml | 7 ++ .../static-server-tcp/servicedefaults.yaml | 7 ++ .../cases/api-gateways/tcproute/route.yaml | 14 +++ .../controllers/gateway_controller.go | 2 +- 14 files changed, 233 insertions(+), 38 deletions(-) create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/anyuid-scc-rolebinding.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/deployment.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/privileged-scc-rolebinding.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/psp-rolebinding.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/service.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/serviceaccount.yaml create mode 100644 acceptance/tests/fixtures/bases/static-server-tcp/servicedefaults.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/tcproute/route.yaml diff --git a/acceptance/go.mod b/acceptance/go.mod index a63e1187fe..e2221a09c0 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -26,18 +26,14 @@ require ( github.com/aws/aws-sdk-go v1.44.262 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect - github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v3 v3.0.0 // indirect - github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deckarep/golang-set v1.7.1 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -46,7 +42,6 @@ require ( github.com/go-openapi/swag v0.22.3 // indirect github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect @@ -54,15 +49,12 @@ require ( github.com/google/gofuzz v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gruntwork-io/gruntwork-cli v0.7.0 // indirect - github.com/hashicorp/consul-server-connection-manager v0.1.2 // indirect - github.com/hashicorp/consul/proto-public v0.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-bexpr v0.1.11 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.2.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-netaddrs v0.1.0 // indirect github.com/hashicorp/go-plugin v1.4.5 // indirect github.com/hashicorp/go-retryablehttp v0.6.6 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect @@ -105,7 +97,6 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.0 // indirect github.com/urfave/cli v1.22.2 // indirect go.uber.org/atomic v1.9.0 // indirect golang.org/x/crypto v0.1.0 // indirect @@ -126,7 +117,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.26.3 // indirect k8s.io/component-base v0.26.3 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index 1c9bd2ad25..77a5b5875a 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -104,12 +104,8 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= -github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v3 v3.0.0 h1:ske+9nBpD9qZsTBoF41nW5L+AIuFBKMeze18XQ3eG1c= github.com/cenkalti/backoff/v3 v3.0.0/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= -github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= @@ -147,8 +143,6 @@ github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= -github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= @@ -195,7 +189,6 @@ github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -254,7 +247,6 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -341,12 +333,8 @@ github.com/gruntwork-io/terratest v0.31.2 h1:xvYHA80MUq5kx670dM18HInewOrrQrAN+Xb github.com/gruntwork-io/terratest v0.31.2/go.mod h1:EEgJie28gX/4AD71IFqgMj6e99KP5mi81hEtzmDjxTo= github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230601034256-0c28b9b000cb h1:9GUvDoKVoV3IW78QyfoNY4bRcKxcn26wTGLoBrz92N4= github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230601034256-0c28b9b000cb/go.mod h1:jKzTEgDc/np2gX/KPdfdm1mEUfZLrU8gc71XN3B15VI= -github.com/hashicorp/consul-server-connection-manager v0.1.2 h1:tNVQHUPuMbd+cMdD8kd+qkZUYpmLmrHMAV/49f4L53I= -github.com/hashicorp/consul-server-connection-manager v0.1.2/go.mod h1:NzQoVi1KcxGI2SangsDue8+ZPuXZWs+6BKAKrDNyg+w= github.com/hashicorp/consul/api v1.10.1-0.20230530193107-04a0d0133ae4 h1:6kUTk+YBgA5X5b3gNAoI18WEK4/t75LcWSimEgmpFdg= github.com/hashicorp/consul/api v1.10.1-0.20230530193107-04a0d0133ae4/go.mod h1:tXfrC6o0yFTgAW46xd5Ic8STHc9oIBcRVBcwhX5KNCQ= -github.com/hashicorp/consul/proto-public v0.1.0 h1:O0LSmCqydZi363hsqc6n2v5sMz3usQMXZF6ziK3SzXU= -github.com/hashicorp/consul/proto-public v0.1.0/go.mod h1:vs2KkuWwtjkIgA5ezp4YKPzQp4GitV+q/+PvksrA92k= github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= github.com/hashicorp/consul/sdk v0.13.1/go.mod h1:SW/mM4LbKfqmMvcFu8v+eiQQ7oitXEFeiBe9StxERb0= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -370,8 +358,6 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-netaddrs v0.1.0 h1:TnlYvODD4C/wO+j7cX1z69kV5gOzI87u3OcUinANaW8= -github.com/hashicorp/go-netaddrs v0.1.0/go.mod h1:33+a/emi5R5dqRspOuZKO0E+Tuz5WV1F84eRWALkedA= github.com/hashicorp/go-plugin v1.4.5 h1:oTE/oQR4eghggRg8VY7PAz3dr++VwDNBGCcOfIvHpBo= github.com/hashicorp/go-plugin v1.4.5/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= @@ -680,7 +666,6 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -872,7 +857,6 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1104,7 +1088,6 @@ k8s.io/api v0.19.3/go.mod h1:VF+5FT1B74Pw3KxMdKyinLo+zynBaMBiAfGMuldcNDs= k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU= k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE= k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE= -k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ= k8s.io/apimachinery v0.17.0/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZg= k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k= diff --git a/acceptance/tests/api-gateway/api_gateway_tenancy_test.go b/acceptance/tests/api-gateway/api_gateway_tenancy_test.go index 2f0005da80..e7748b9226 100644 --- a/acceptance/tests/api-gateway/api_gateway_tenancy_test.go +++ b/acceptance/tests/api-gateway/api_gateway_tenancy_test.go @@ -288,7 +288,7 @@ type certificateInfo struct { func generateCertificate(t *testing.T, ca *certificateInfo, commonName string) *certificateInfo { t.Helper() - bits := 1024 + bits := 2048 privateKey, err := rsa.GenerateKey(rand.Reader, bits) require.NoError(t, err) diff --git a/acceptance/tests/api-gateway/api_gateway_test.go b/acceptance/tests/api-gateway/api_gateway_test.go index 2291587bcc..17234cadf1 100644 --- a/acceptance/tests/api-gateway/api_gateway_test.go +++ b/acceptance/tests/api-gateway/api_gateway_test.go @@ -5,7 +5,9 @@ package apigateway import ( "context" + "encoding/base64" "fmt" + gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" "strconv" "testing" "time" @@ -79,12 +81,39 @@ func TestAPIGateway_Basic(t *testing.T) { k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-k", "../fixtures/bases/api-gateway") }) - logger.Log(t, "creating target server") + // Create certificate secret, we do this separately since + // applying the secret will make an invalid certificate that breaks other tests + logger.Log(t, "creating certificate secret") + out, err = k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-f", "../fixtures/bases/api-gateway/certificate.yaml") + require.NoError(t, err, out) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + // Ignore errors here because if the test ran as expected + // the custom resources will have been deleted. + k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-f", "../fixtures/bases/api-gateway/certificate.yaml") + }) + + // patch certificate with data + logger.Log(t, "patching certificate secret with generated data") + certificate := generateCertificate(t, nil, "gateway.test.local") + k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "secret", "certificate", "-p", fmt.Sprintf(`{"data":{"tls.crt":"%s","tls.key":"%s"}}`, base64.StdEncoding.EncodeToString(certificate.CertPEM), base64.StdEncoding.EncodeToString(certificate.PrivateKeyPEM)), "--type=merge") + + logger.Log(t, "creating target http server") k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") - logger.Log(t, "patching route to target server") + logger.Log(t, "patching route to target http server") k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "httproute", "http-route", "-p", `{"spec":{"rules":[{"backendRefs":[{"name":"static-server","port":80}]}]}}`, "--type=merge") + logger.Log(t, "creating target tcp server") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server-tcp") + + logger.Log(t, "creating tcp-route") + k8s.RunKubectl(t, ctx.KubectlOptions(t), "apply", "-f", "../fixtures/cases/api-gateways/tcproute/route.yaml") + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + // Ignore errors here because if the test ran as expected + // the custom resources will have been deleted. + k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-f", "../fixtures/cases/api-gateways/tcproute/route.yaml") + }) + // We use the static-client pod so that we can make calls to the api gateway // via kubectl exec without needing a route into the cluster from the test machine. logger.Log(t, "creating static-client pod") @@ -112,18 +141,19 @@ func TestAPIGateway_Basic(t *testing.T) { checkStatusCondition(r, gateway.Status.Conditions, trueCondition("Accepted", "Accepted")) checkStatusCondition(r, gateway.Status.Conditions, trueCondition("ConsulAccepted", "Accepted")) require.Len(r, gateway.Status.Listeners, 3) + require.EqualValues(r, 1, gateway.Status.Listeners[0].AttachedRoutes) checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, trueCondition("Accepted", "Accepted")) checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, falseCondition("Conflicted", "NoConflicts")) checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) - require.EqualValues(r, 0, gateway.Status.Listeners[1].AttachedRoutes) + require.EqualValues(r, 1, gateway.Status.Listeners[1].AttachedRoutes) checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, trueCondition("Accepted", "Accepted")) checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, falseCondition("Conflicted", "NoConflicts")) checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) require.EqualValues(r, 1, gateway.Status.Listeners[2].AttachedRoutes) checkStatusCondition(r, gateway.Status.Listeners[2].Conditions, trueCondition("Accepted", "Accepted")) checkStatusCondition(r, gateway.Status.Listeners[2].Conditions, falseCondition("Conflicted", "NoConflicts")) - checkStatusCondition(r, gateway.Status.Listeners[2].Conditions, falseCondition("ResolvedRefs", "InvalidCertificateRef")) + checkStatusCondition(r, gateway.Status.Listeners[2].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) // check that we have an address to use require.Len(r, gateway.Status.Addresses, 1) @@ -160,6 +190,23 @@ func TestAPIGateway_Basic(t *testing.T) { checkStatusCondition(t, httproute.Status.Parents[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) checkStatusCondition(t, httproute.Status.Parents[0].Conditions, trueCondition("ConsulAccepted", "Accepted")) + // tcp route checks + var tcpRoute gwv1alpha2.TCPRoute + err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "tcp-route", Namespace: "default"}, &tcpRoute) + require.NoError(t, err) + + // check our finalizers + require.Len(t, tcpRoute.Finalizers, 1) + require.EqualValues(t, gatewayFinalizer, tcpRoute.Finalizers[0]) + + // check parent status + require.Len(t, tcpRoute.Status.Parents, 1) + require.EqualValues(t, gatewayClassControllerName, tcpRoute.Status.Parents[0].ControllerName) + require.EqualValues(t, "gateway", tcpRoute.Status.Parents[0].ParentRef.Name) + checkStatusCondition(t, tcpRoute.Status.Parents[0].Conditions, trueCondition("Accepted", "Accepted")) + checkStatusCondition(t, tcpRoute.Status.Parents[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) + checkStatusCondition(t, tcpRoute.Status.Parents[0].Conditions, trueCondition("ConsulAccepted", "Accepted")) + // check that the Consul entries were created entry, _, err := consulClient.ConfigEntries().Get(api.APIGateway, "gateway", nil) require.NoError(t, err) @@ -167,21 +214,32 @@ func TestAPIGateway_Basic(t *testing.T) { entry, _, err = consulClient.ConfigEntries().Get(api.HTTPRoute, "http-route", nil) require.NoError(t, err) - route := entry.(*api.HTTPRouteConfigEntry) + httpRoute := entry.(*api.HTTPRouteConfigEntry) + + entry, _, err = consulClient.ConfigEntries().Get(api.TCPRoute, "tcp-route", nil) + require.NoError(t, err) + route := entry.(*api.TCPRouteConfigEntry) // now check the gateway status conditions checkConsulStatusCondition(t, gateway.Status.Conditions, trueConsulCondition("Accepted", "Accepted")) // and the route status conditions + checkConsulStatusCondition(t, httpRoute.Status.Conditions, trueConsulCondition("Bound", "Bound")) checkConsulStatusCondition(t, route.Status.Conditions, trueConsulCondition("Bound", "Bound")) // finally we check that we can actually route to the service via the gateway k8sOptions := ctx.KubectlOptions(t) - targetAddress := fmt.Sprintf("http://%s/", gatewayAddress) + targetHTTPAddress := fmt.Sprintf("http://%s", gatewayAddress) + targetHTTPSAddress := fmt.Sprintf("https://%s", gatewayAddress) + targetTCPAddress := fmt.Sprintf("http://%s:81", gatewayAddress) if c.secure { // check that intentions keep our connection from happening - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetAddress) + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddress) + + k8s.CheckStaticServerConnectionFailing(t, k8sOptions, StaticClientName, targetTCPAddress) + + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-k", targetHTTPSAddress) // Now we create the allow intention. _, _, err = consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ @@ -195,12 +253,31 @@ func TestAPIGateway_Basic(t *testing.T) { }, }, nil) require.NoError(t, err) + + // Now we create the allow intention tcp. + _, _, err = consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ + Kind: api.ServiceIntentions, + Name: "static-server-tcp", + Sources: []*api.SourceIntention{ + { + Name: "gateway", + Action: api.IntentionActionAllow, + }, + }, + }, nil) + require.NoError(t, err) } // Test that we can make a call to the api gateway // via the static-client pod. It should route to the static-server pod. - logger.Log(t, "trying calls to api gateway") - k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, targetAddress) + logger.Log(t, "trying calls to api gateway http") + k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, targetHTTPAddress) + + logger.Log(t, "trying calls to api gateway tcp") + k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, targetTCPAddress) + + logger.Log(t, "trying calls to api gateway https") + k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, targetHTTPSAddress, "-k") }) } } diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/anyuid-scc-rolebinding.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/anyuid-scc-rolebinding.yaml new file mode 100644 index 0000000000..eb86dc8bae --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/anyuid-scc-rolebinding.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: static-server-tcp-openshift-anyuid +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: static-server-tcp \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/deployment.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/deployment.yaml new file mode 100644 index 0000000000..9aa5177e9e --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/deployment.yaml @@ -0,0 +1,49 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: static-server-tcp + name: static-server-tcp +spec: + replicas: 1 + selector: + matchLabels: + app: static-server-tcp + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + labels: + app: static-server-tcp + spec: + containers: + - name: static-server + image: docker.mirror.hashicorp.services/kschoche/http-echo:latest + args: + - -text="hello world" + - -listen=:8080 + ports: + - containerPort: 8080 + name: http + livenessProbe: + httpGet: + port: 8080 + initialDelaySeconds: 1 + failureThreshold: 1 + periodSeconds: 1 + startupProbe: + httpGet: + port: 8080 + initialDelaySeconds: 1 + failureThreshold: 30 + periodSeconds: 1 + readinessProbe: + exec: + command: ['sh', '-c', 'test ! -f /tmp/unhealthy'] + initialDelaySeconds: 1 + failureThreshold: 1 + periodSeconds: 1 + serviceAccountName: static-server-tcp diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/kustomization.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/kustomization.yaml new file mode 100644 index 0000000000..2180aa94e1 --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/kustomization.yaml @@ -0,0 +1,11 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - deployment.yaml + - service.yaml + - serviceaccount.yaml + - servicedefaults.yaml + - psp-rolebinding.yaml + - anyuid-scc-rolebinding.yaml + - privileged-scc-rolebinding.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/privileged-scc-rolebinding.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/privileged-scc-rolebinding.yaml new file mode 100644 index 0000000000..ac28006765 --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/privileged-scc-rolebinding.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: static-server-tcp-openshift-privileged +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:privileged +subjects: + - kind: ServiceAccount + name: static-server-tcp \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/psp-rolebinding.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/psp-rolebinding.yaml new file mode 100644 index 0000000000..f4f008dbea --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/psp-rolebinding.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: static-server-tcp +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: test-psp +subjects: + - kind: ServiceAccount + name: static-server-tcp \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/service.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/service.yaml new file mode 100644 index 0000000000..6ceccf940a --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/service.yaml @@ -0,0 +1,15 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: static-server-tcp + labels: + app: static-server-tcp +spec: + ports: + - name: http + port: 8080 + selector: + app: static-server-tcp diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/serviceaccount.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/serviceaccount.yaml new file mode 100644 index 0000000000..af2247af8e --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/serviceaccount.yaml @@ -0,0 +1,7 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: static-server-tcp diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/servicedefaults.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/servicedefaults.yaml new file mode 100644 index 0000000000..500051db87 --- /dev/null +++ b/acceptance/tests/fixtures/bases/static-server-tcp/servicedefaults.yaml @@ -0,0 +1,7 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceDefaults +metadata: + name: static-server-tcp + namespace: default +spec: + protocol: tcp \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/api-gateways/tcproute/route.yaml b/acceptance/tests/fixtures/cases/api-gateways/tcproute/route.yaml new file mode 100644 index 0000000000..37602c65af --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/tcproute/route.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: gateway.networking.k8s.io/v1alpha2 +kind: TCPRoute +metadata: + name: tcp-route +spec: + parentRefs: + - name: gateway + rules: + - backendRefs: + - kind: Service + name: static-server-tcp \ No newline at end of file diff --git a/control-plane/api-gateway/controllers/gateway_controller.go b/control-plane/api-gateway/controllers/gateway_controller.go index ab2b6af1a5..ec8c2e9af0 100644 --- a/control-plane/api-gateway/controllers/gateway_controller.go +++ b/control-plane/api-gateway/controllers/gateway_controller.go @@ -191,7 +191,7 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct if updates.UpsertGatewayDeployment { if err := r.cache.EnsureRoleBinding(r.HelmConfig.AuthMethod, gateway.Name, gateway.Namespace); err != nil { - log.Error(err, "error linking token policy") + log.Error(err, "error creating role binding") return ctrl.Result{}, err } From 555d4a64a498c2f7462f3659c3858f2430f5c8e3 Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Fri, 9 Jun 2023 00:31:40 -0400 Subject: [PATCH 006/120] [API Gateway] Add acceptance test for cluster peering (#2306) * [API Gateway] Add acceptance test for cluster peering * Fix linter * Fix random unrelated linter errors to get CI to run: revert later? * one more linter fix to later probably revert * more linter fixes * Revert "more linter fixes" This reverts commit 6210dff0e51bbcf2f754f6d666c08292ba958aaa. * Revert "one more linter fix to later probably revert" This reverts commit 030c563bbe0b0a9ef73b33cbea32464416156d8f. * Revert "Fix random unrelated linter errors to get CI to run: revert later?" This reverts commit fdeccabb2f6c4418168cad9be5b2459435b7e30b. --- .../peer-resolver/kustomization.yaml | 5 + .../peer-resolver/serviceresolver.yaml | 12 + .../tests/peering/peering_gateway_test.go | 291 ++++++++++++++++++ 3 files changed, 308 insertions(+) create mode 100644 acceptance/tests/fixtures/cases/api-gateways/peer-resolver/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/peer-resolver/serviceresolver.yaml create mode 100644 acceptance/tests/peering/peering_gateway_test.go diff --git a/acceptance/tests/fixtures/cases/api-gateways/peer-resolver/kustomization.yaml b/acceptance/tests/fixtures/cases/api-gateways/peer-resolver/kustomization.yaml new file mode 100644 index 0000000000..cdbcd688c0 --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/peer-resolver/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - serviceresolver.yaml diff --git a/acceptance/tests/fixtures/cases/api-gateways/peer-resolver/serviceresolver.yaml b/acceptance/tests/fixtures/cases/api-gateways/peer-resolver/serviceresolver.yaml new file mode 100644 index 0000000000..20874fe1f9 --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/peer-resolver/serviceresolver.yaml @@ -0,0 +1,12 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceResolver +metadata: + name: static-server +spec: + redirect: + peer: server + namespace: ns1 + service: static-server \ No newline at end of file diff --git a/acceptance/tests/peering/peering_gateway_test.go b/acceptance/tests/peering/peering_gateway_test.go new file mode 100644 index 0000000000..76698102e6 --- /dev/null +++ b/acceptance/tests/peering/peering_gateway_test.go @@ -0,0 +1,291 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package peering + +import ( + "context" + "fmt" + "testing" + "time" + + terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" + "github.com/hashicorp/consul-k8s/acceptance/framework/environment" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/hashicorp/go-version" + "github.com/stretchr/testify/require" + "k8s.io/apimachinery/pkg/types" + + gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" +) + +func TestPeering_Gateway(t *testing.T) { + env := suite.Environment() + cfg := suite.Config() + + if !cfg.EnableEnterprise { + t.Skipf("skipping this test because -enable-enterprise is not set") + } + + ver, err := version.NewVersion("1.13.0") + require.NoError(t, err) + if cfg.ConsulVersion != nil && cfg.ConsulVersion.LessThan(ver) { + t.Skipf("skipping this test because peering is not supported in version %v", cfg.ConsulVersion.String()) + } + + const staticServerPeer = "server" + const staticClientPeer = "client" + + staticServerPeerClusterContext := env.DefaultContext(t) + staticClientPeerClusterContext := env.Context(t, environment.SecondaryContextName) + + commonHelmValues := map[string]string{ + "global.peering.enabled": "true", + "global.enableConsulNamespaces": "true", + + "global.tls.enabled": "true", + "global.tls.httpsOnly": "true", + + "global.acls.manageSystemACLs": "true", + + "connectInject.enabled": "true", + + // When mirroringK8S is set, this setting is ignored. + "connectInject.consulNamespaces.mirroringK8S": "true", + + "meshGateway.enabled": "true", + "meshGateway.replicas": "1", + + "dns.enabled": "true", + } + + staticServerPeerHelmValues := map[string]string{ + "global.datacenter": staticServerPeer, + } + + if !cfg.UseKind { + staticServerPeerHelmValues["server.replicas"] = "3" + } + + // On Kind, there are no load balancers but since all clusters + // share the same node network (docker bridge), we can use + // a NodePort service so that we can access node(s) in a different Kind cluster. + if cfg.UseKind { + staticServerPeerHelmValues["server.exposeGossipAndRPCPorts"] = "true" + staticServerPeerHelmValues["meshGateway.service.type"] = "NodePort" + staticServerPeerHelmValues["meshGateway.service.nodePort"] = "30100" + } + + releaseName := helpers.RandomName() + + helpers.MergeMaps(staticServerPeerHelmValues, commonHelmValues) + + // Install the first peer where static-server will be deployed in the static-server kubernetes context. + staticServerPeerCluster := consul.NewHelmCluster(t, staticServerPeerHelmValues, staticServerPeerClusterContext, cfg, releaseName) + staticServerPeerCluster.Create(t) + + staticClientPeerHelmValues := map[string]string{ + "global.datacenter": staticClientPeer, + } + + if !cfg.UseKind { + staticClientPeerHelmValues["server.replicas"] = "3" + } + + if cfg.UseKind { + staticClientPeerHelmValues["server.exposeGossipAndRPCPorts"] = "true" + staticClientPeerHelmValues["meshGateway.service.type"] = "NodePort" + staticClientPeerHelmValues["meshGateway.service.nodePort"] = "30100" + } + + helpers.MergeMaps(staticClientPeerHelmValues, commonHelmValues) + + // Install the second peer where static-client will be deployed in the static-client kubernetes context. + staticClientPeerCluster := consul.NewHelmCluster(t, staticClientPeerHelmValues, staticClientPeerClusterContext, cfg, releaseName) + staticClientPeerCluster.Create(t) + + // Create Mesh resource to use mesh gateways. + logger.Log(t, "creating mesh config") + kustomizeMeshDir := "../fixtures/bases/mesh-peering" + + k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) + }) + + k8s.KubectlApplyK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) + }) + + staticServerPeerClient, _ := staticServerPeerCluster.SetupConsulClient(t, true) + staticClientPeerClient, _ := staticClientPeerCluster.SetupConsulClient(t, true) + + // Ensure mesh config entries are created in Consul. + timer := &retry.Timer{Timeout: 1 * time.Minute, Wait: 1 * time.Second} + retry.RunWith(timer, t, func(r *retry.R) { + ceServer, _, err := staticServerPeerClient.ConfigEntries().Get(api.MeshConfig, "mesh", &api.QueryOptions{}) + require.NoError(r, err) + configEntryServer, ok := ceServer.(*api.MeshConfigEntry) + require.True(r, ok) + require.Equal(r, configEntryServer.GetName(), "mesh") + require.NoError(r, err) + + ceClient, _, err := staticClientPeerClient.ConfigEntries().Get(api.MeshConfig, "mesh", &api.QueryOptions{}) + require.NoError(r, err) + configEntryClient, ok := ceClient.(*api.MeshConfigEntry) + require.True(r, ok) + require.Equal(r, configEntryClient.GetName(), "mesh") + require.NoError(r, err) + }) + + // Create the peering acceptor on the client peer. + k8s.KubectlApply(t, staticClientPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-acceptor.yaml") + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDelete(t, staticClientPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-acceptor.yaml") + }) + + // Ensure the secret is created. + retry.RunWith(timer, t, func(r *retry.R) { + acceptorSecretName, err := k8s.RunKubectlAndGetOutputE(t, staticClientPeerClusterContext.KubectlOptions(t), "get", "peeringacceptor", "server", "-o", "jsonpath={.status.secret.name}") + require.NoError(r, err) + require.NotEmpty(r, acceptorSecretName) + }) + + // Copy secret from client peer to server peer. + k8s.CopySecret(t, staticClientPeerClusterContext, staticServerPeerClusterContext, "api-token") + + // Create the peering dialer on the server peer. + k8s.KubectlApply(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-dialer.yaml") + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "delete", "secret", "api-token") + k8s.KubectlDelete(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-dialer.yaml") + }) + + staticServerOpts := &terratestk8s.KubectlOptions{ + ContextName: staticServerPeerClusterContext.KubectlOptions(t).ContextName, + ConfigPath: staticServerPeerClusterContext.KubectlOptions(t).ConfigPath, + Namespace: staticServerNamespace, + } + staticClientOpts := &terratestk8s.KubectlOptions{ + ContextName: staticClientPeerClusterContext.KubectlOptions(t).ContextName, + ConfigPath: staticClientPeerClusterContext.KubectlOptions(t).ConfigPath, + Namespace: staticClientNamespace, + } + + logger.Logf(t, "creating namespaces %s in server peer", staticServerNamespace) + k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace) + }) + + logger.Logf(t, "creating namespaces %s in client peer", staticClientNamespace) + k8s.RunKubectl(t, staticClientPeerClusterContext.KubectlOptions(t), "create", "ns", staticClientNamespace) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.RunKubectl(t, staticClientPeerClusterContext.KubectlOptions(t), "delete", "ns", staticClientNamespace) + }) + + // Create a ProxyDefaults resource to configure services to use the mesh + // gateways. + logger.Log(t, "creating proxy-defaults config") + kustomizeDir := "../fixtures/cases/api-gateways/mesh" + + k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeDir) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeDir) + }) + + k8s.KubectlApplyK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeDir) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeDir) + }) + + // We use the static-client pod so that we can make calls to the api gateway + // via kubectl exec without needing a route into the cluster from the test machine. + // Since we're deploying the gateway in the secondary cluster, we create the static client + // in the secondary as well. + logger.Log(t, "creating static-client pod in client peer") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/non-default-namespace") + + logger.Log(t, "creating static-server in server peer") + k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + + logger.Log(t, "creating exported services") + k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/non-default-namespace") + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/non-default-namespace") + }) + + logger.Log(t, "creating api-gateway resources in client peer") + out, err := k8s.RunKubectlAndGetOutputE(t, staticClientOpts, "apply", "-k", "../fixtures/bases/api-gateway") + require.NoError(t, err, out) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + // Ignore errors here because if the test ran as expected + // the custom resources will have been deleted. + k8s.RunKubectlAndGetOutputE(t, staticClientOpts, "delete", "-k", "../fixtures/bases/api-gateway") + }) + + // Grab a kubernetes client so that we can verify binding + // behavior prior to issuing requests through the gateway. + k8sClient := staticClientPeerClusterContext.ControllerRuntimeClient(t) + + // On startup, the controller can take upwards of 1m to perform + // leader election so we may need to wait a long time for + // the reconcile loop to run (hence the 1m timeout here). + var gatewayAddress string + counter := &retry.Counter{Count: 600, Wait: 2 * time.Second} + retry.RunWith(counter, t, func(r *retry.R) { + var gateway gwv1beta1.Gateway + err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: staticClientNamespace}, &gateway) + require.NoError(r, err) + + // check that we have an address to use + require.Len(r, gateway.Status.Addresses, 1) + // now we know we have an address, set it so we can use it + gatewayAddress = gateway.Status.Addresses[0].Value + }) + + targetAddress := fmt.Sprintf("http://%s/", gatewayAddress) + + logger.Log(t, "creating local service resolver") + k8s.KubectlApplyK(t, staticClientOpts, "../fixtures/cases/api-gateways/peer-resolver") + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, staticClientOpts, "../fixtures/cases/api-gateways/peer-resolver") + }) + + logger.Log(t, "patching route to target server") + k8s.RunKubectl(t, staticClientOpts, "patch", "httproute", "http-route", "-p", `{"spec":{"rules":[{"backendRefs":[{"group":"consul.hashicorp.com","kind":"MeshService","name":"mesh-service","port":80}]}]}}`, "--type=merge") + + logger.Log(t, "checking that the connection is not successful because there's no intention") + k8s.CheckStaticServerHTTPConnectionFailing(t, staticClientOpts, staticClientName, targetAddress) + + intention := &api.ServiceIntentionsConfigEntry{ + Kind: api.ServiceIntentions, + Name: staticServerName, + Namespace: staticServerNamespace, + Sources: []*api.SourceIntention{ + { + Name: "gateway", + Namespace: staticClientNamespace, + Action: api.IntentionActionAllow, + Peer: staticClientPeer, + }, + }, + } + + logger.Log(t, "creating intention") + _, _, err = staticServerPeerClient.ConfigEntries().Set(intention, &api.WriteOptions{}) + require.NoError(t, err) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + _, err = staticServerPeerClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{}) + require.NoError(t, err) + }) + + logger.Log(t, "checking that connection is successful") + k8s.CheckStaticServerConnectionSuccessful(t, staticClientOpts, staticClientName, targetAddress) +} From b56b7dd4d7d90189d73a71b6a154a89ddafcd511 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Thu, 8 Jun 2023 22:39:08 -0700 Subject: [PATCH 007/120] Mw/net 3598 update kind for consul k8s acceptance tests with latest version of kind and k8s 1.27 (#2304) * update cloud tests to use 1.24, 1.25 and 1.26 version of kubernetes for more coverage * updated readme for supported kubernetes versions * added changelog --- .changelog/2304.txt | 3 +++ README.md | 2 +- charts/consul/test/terraform/aks/main.tf | 2 +- charts/consul/test/terraform/gke/main.tf | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 .changelog/2304.txt diff --git a/.changelog/2304.txt b/.changelog/2304.txt new file mode 100644 index 0000000000..c977da5acd --- /dev/null +++ b/.changelog/2304.txt @@ -0,0 +1,3 @@ +```release-note:improvement +helm: Kubernetes v1.27 is now supported. Minimum tested version of Kubernetes is now v1.24. +``` diff --git a/README.md b/README.md index 1d3a3733ab..d43a12b455 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ by contacting us at [security@hashicorp.com](mailto:security@hashicorp.com). The following pre-requisites must be met before installing Consul on Kubernetes. - * **Kubernetes 1.23.x - 1.26.x** - This represents the earliest versions of Kubernetes tested. + * **Kubernetes 1.24.x - 1.27.x** - This represents the earliest versions of Kubernetes tested. It is possible that this chart works with earlier versions, but it is untested. * Helm install diff --git a/charts/consul/test/terraform/aks/main.tf b/charts/consul/test/terraform/aks/main.tf index bf8c925f15..2683bdc1a7 100644 --- a/charts/consul/test/terraform/aks/main.tf +++ b/charts/consul/test/terraform/aks/main.tf @@ -55,7 +55,7 @@ resource "azurerm_kubernetes_cluster" "default" { location = azurerm_resource_group.default[count.index].location resource_group_name = azurerm_resource_group.default[count.index].name dns_prefix = "consul-k8s-${random_id.suffix[count.index].dec}" - kubernetes_version = "1.26" + kubernetes_version = "1.24.10" role_based_access_control_enabled = true // We're setting the network plugin and other network properties explicitly diff --git a/charts/consul/test/terraform/gke/main.tf b/charts/consul/test/terraform/gke/main.tf index fe5adc5e8d..34bb07906f 100644 --- a/charts/consul/test/terraform/gke/main.tf +++ b/charts/consul/test/terraform/gke/main.tf @@ -21,7 +21,7 @@ resource "random_id" "suffix" { data "google_container_engine_versions" "main" { location = var.zone - version_prefix = "1.25." + version_prefix = "1.25.9" } # We assume that the subnets are already created to save time. From 203c9d19766209460e782f650536795b9b82e668 Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Fri, 9 Jun 2023 09:53:16 -0400 Subject: [PATCH 008/120] [API Gateway] WAN Federation test and fixes (#2295) * [API Gateway] WAN Federation test and fixes * Fix unit tests --- .../dc1-to-dc2-resolver/kustomization.yaml | 5 + .../dc1-to-dc2-resolver/serviceresolver.yaml | 11 + .../dc2-to-dc1-resolver/kustomization.yaml | 5 + .../dc2-to-dc1-resolver/serviceresolver.yaml | 11 + .../wan_federation_gateway_test.go | 241 ++++++++++++++++++ control-plane/api-gateway/cache/consul.go | 19 ++ .../api-gateway/cache/consul_test.go | 124 ++++++--- .../api-gateway/common/helm_config.go | 24 +- .../api-gateway/common/translation.go | 25 +- .../controllers/gateway_controller.go | 5 +- .../api/v1alpha1/serviceresolver_types.go | 2 +- .../connect-inject/constants/constants.go | 3 + .../subcommand/inject-connect/command.go | 2 + 13 files changed, 427 insertions(+), 50 deletions(-) create mode 100644 acceptance/tests/fixtures/cases/api-gateways/dc1-to-dc2-resolver/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/dc1-to-dc2-resolver/serviceresolver.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/dc2-to-dc1-resolver/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/dc2-to-dc1-resolver/serviceresolver.yaml create mode 100644 acceptance/tests/wan-federation/wan_federation_gateway_test.go diff --git a/acceptance/tests/fixtures/cases/api-gateways/dc1-to-dc2-resolver/kustomization.yaml b/acceptance/tests/fixtures/cases/api-gateways/dc1-to-dc2-resolver/kustomization.yaml new file mode 100644 index 0000000000..cdbcd688c0 --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/dc1-to-dc2-resolver/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - serviceresolver.yaml diff --git a/acceptance/tests/fixtures/cases/api-gateways/dc1-to-dc2-resolver/serviceresolver.yaml b/acceptance/tests/fixtures/cases/api-gateways/dc1-to-dc2-resolver/serviceresolver.yaml new file mode 100644 index 0000000000..ca009754b4 --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/dc1-to-dc2-resolver/serviceresolver.yaml @@ -0,0 +1,11 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceResolver +metadata: + name: static-server +spec: + redirect: + service: static-server + datacenter: dc2 \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/api-gateways/dc2-to-dc1-resolver/kustomization.yaml b/acceptance/tests/fixtures/cases/api-gateways/dc2-to-dc1-resolver/kustomization.yaml new file mode 100644 index 0000000000..cdbcd688c0 --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/dc2-to-dc1-resolver/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - serviceresolver.yaml diff --git a/acceptance/tests/fixtures/cases/api-gateways/dc2-to-dc1-resolver/serviceresolver.yaml b/acceptance/tests/fixtures/cases/api-gateways/dc2-to-dc1-resolver/serviceresolver.yaml new file mode 100644 index 0000000000..af8cdb72ed --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/dc2-to-dc1-resolver/serviceresolver.yaml @@ -0,0 +1,11 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceResolver +metadata: + name: static-server +spec: + redirect: + service: static-server + datacenter: dc1 \ No newline at end of file diff --git a/acceptance/tests/wan-federation/wan_federation_gateway_test.go b/acceptance/tests/wan-federation/wan_federation_gateway_test.go new file mode 100644 index 0000000000..0ef48b9920 --- /dev/null +++ b/acceptance/tests/wan-federation/wan_federation_gateway_test.go @@ -0,0 +1,241 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package wanfederation + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" + "github.com/hashicorp/consul-k8s/acceptance/framework/environment" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/serf/testutil/retry" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" +) + +func TestWANFederation_Gateway(t *testing.T) { + env := suite.Environment() + cfg := suite.Config() + + if cfg.UseKind { + // the only way this test can currently run on kind, at least on a Mac, is via leveraging MetalLB, which + // isn't in CI, so we just skip for now. + t.Skipf("skipping wan federation tests as they currently fail on Kind even though they work on other clouds.") + } + + primaryContext := env.DefaultContext(t) + secondaryContext := env.Context(t, environment.SecondaryContextName) + + primaryHelmValues := map[string]string{ + "global.datacenter": "dc1", + + "global.tls.enabled": "true", + "global.tls.httpsOnly": "true", + + "global.federation.enabled": "true", + "global.federation.createFederationSecret": "true", + + "global.acls.manageSystemACLs": "true", + "global.acls.createReplicationToken": "true", + + "connectInject.enabled": "true", + "connectInject.replicas": "1", + + "meshGateway.enabled": "true", + "meshGateway.replicas": "1", + } + + releaseName := helpers.RandomName() + + // Install the primary consul cluster in the default kubernetes context + primaryConsulCluster := consul.NewHelmCluster(t, primaryHelmValues, primaryContext, cfg, releaseName) + primaryConsulCluster.Create(t) + + // Get the federation secret from the primary cluster and apply it to secondary cluster + federationSecretName := fmt.Sprintf("%s-consul-federation", releaseName) + logger.Logf(t, "retrieving federation secret %s from the primary cluster and applying to the secondary", federationSecretName) + federationSecret, err := primaryContext.KubernetesClient(t).CoreV1().Secrets(primaryContext.KubectlOptions(t).Namespace).Get(context.Background(), federationSecretName, metav1.GetOptions{}) + require.NoError(t, err) + federationSecret.ResourceVersion = "" + _, err = secondaryContext.KubernetesClient(t).CoreV1().Secrets(secondaryContext.KubectlOptions(t).Namespace).Create(context.Background(), federationSecret, metav1.CreateOptions{}) + require.NoError(t, err) + + var k8sAuthMethodHost string + // When running on kind, the kube API address in kubeconfig will have a localhost address + // which will not work from inside the container. That's why we need to use the endpoints address instead + // which will point the node IP. + if cfg.UseKind { + // The Kubernetes AuthMethod host is read from the endpoints for the Kubernetes service. + kubernetesEndpoint, err := secondaryContext.KubernetesClient(t).CoreV1().Endpoints("default").Get(context.Background(), "kubernetes", metav1.GetOptions{}) + require.NoError(t, err) + k8sAuthMethodHost = fmt.Sprintf("%s:%d", kubernetesEndpoint.Subsets[0].Addresses[0].IP, kubernetesEndpoint.Subsets[0].Ports[0].Port) + } else { + k8sAuthMethodHost = k8s.KubernetesAPIServerHostFromOptions(t, secondaryContext.KubectlOptions(t)) + } + + // Create secondary cluster + secondaryHelmValues := map[string]string{ + "global.datacenter": "dc2", + + "global.tls.enabled": "true", + "global.tls.httpsOnly": "false", + "global.acls.manageSystemACLs": "true", + "global.tls.caCert.secretName": federationSecretName, + "global.tls.caCert.secretKey": "caCert", + "global.tls.caKey.secretName": federationSecretName, + "global.tls.caKey.secretKey": "caKey", + + "global.federation.enabled": "true", + + "server.extraVolumes[0].type": "secret", + "server.extraVolumes[0].name": federationSecretName, + "server.extraVolumes[0].load": "true", + "server.extraVolumes[0].items[0].key": "serverConfigJSON", + "server.extraVolumes[0].items[0].path": "config.json", + + "connectInject.enabled": "true", + "connectInject.replicas": "1", + + "meshGateway.enabled": "true", + "meshGateway.replicas": "1", + + "global.acls.replicationToken.secretName": federationSecretName, + "global.acls.replicationToken.secretKey": "replicationToken", + "global.federation.k8sAuthMethodHost": k8sAuthMethodHost, + "global.federation.primaryDatacenter": "dc1", + } + + // Install the secondary consul cluster in the secondary kubernetes context + secondaryConsulCluster := consul.NewHelmCluster(t, secondaryHelmValues, secondaryContext, cfg, releaseName) + secondaryConsulCluster.Create(t) + + primaryClient, _ := primaryConsulCluster.SetupConsulClient(t, true) + secondaryClient, _ := secondaryConsulCluster.SetupConsulClient(t, true) + + // Verify federation between servers + logger.Log(t, "verifying federation was successful") + helpers.VerifyFederation(t, primaryClient, secondaryClient, releaseName, true) + + // Create a ProxyDefaults resource to configure services to use the mesh + // gateways. + logger.Log(t, "creating proxy-defaults config in dc1") + kustomizeDir := "../fixtures/cases/api-gateways/mesh" + k8s.KubectlApplyK(t, primaryContext.KubectlOptions(t), kustomizeDir) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, primaryContext.KubectlOptions(t), kustomizeDir) + }) + + // these clients are just there so we can exec in and curl on them. + logger.Log(t, "creating static-client in dc1") + k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") + + logger.Log(t, "creating static-client in dc2") + k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") + + t.Run("from primary to secondary", func(t *testing.T) { + logger.Log(t, "creating static-server in dc2") + k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + + logger.Log(t, "creating api-gateway resources in dc1") + out, err := k8s.RunKubectlAndGetOutputE(t, primaryContext.KubectlOptions(t), "apply", "-k", "../fixtures/bases/api-gateway") + require.NoError(t, err, out) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + // Ignore errors here because if the test ran as expected + // the custom resources will have been deleted. + k8s.RunKubectlAndGetOutputE(t, primaryContext.KubectlOptions(t), "delete", "-k", "../fixtures/bases/api-gateway") + }) + + // create a service resolver for doing cross-dc redirects. + k8s.KubectlApplyK(t, secondaryContext.KubectlOptions(t), "../fixtures/cases/api-gateways/dc1-to-dc2-resolver") + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, secondaryContext.KubectlOptions(t), "../fixtures/cases/api-gateways/dc1-to-dc2-resolver") + }) + + // patching the route to target a MeshService since we don't have the corresponding Kubernetes service in this + // cluster. + k8s.RunKubectl(t, primaryContext.KubectlOptions(t), "patch", "httproute", "http-route", "-p", `{"spec":{"rules":[{"backendRefs":[{"group":"consul.hashicorp.com","kind":"MeshService","name":"mesh-service","port":80}]}]}}`, "--type=merge") + + checkConnectivity(t, primaryContext, primaryClient) + }) + + t.Run("from secondary to primary", func(t *testing.T) { + // Check that we can connect services over the mesh gateways + logger.Log(t, "creating static-server in dc1") + k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + + logger.Log(t, "creating api-gateway resources in dc2") + out, err := k8s.RunKubectlAndGetOutputE(t, secondaryContext.KubectlOptions(t), "apply", "-k", "../fixtures/bases/api-gateway") + require.NoError(t, err, out) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + // Ignore errors here because if the test ran as expected + // the custom resources will have been deleted. + k8s.RunKubectlAndGetOutputE(t, secondaryContext.KubectlOptions(t), "delete", "-k", "../fixtures/bases/api-gateway") + }) + + // create a service resolver for doing cross-dc redirects. + k8s.KubectlApplyK(t, secondaryContext.KubectlOptions(t), "../fixtures/cases/api-gateways/dc2-to-dc1-resolver") + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, secondaryContext.KubectlOptions(t), "../fixtures/cases/api-gateways/dc2-to-dc1-resolver") + }) + + // patching the route to target a MeshService since we don't have the corresponding Kubernetes service in this + // cluster. + k8s.RunKubectl(t, secondaryContext.KubectlOptions(t), "patch", "httproute", "http-route", "-p", `{"spec":{"rules":[{"backendRefs":[{"group":"consul.hashicorp.com","kind":"MeshService","name":"mesh-service","port":80}]}]}}`, "--type=merge") + + checkConnectivity(t, secondaryContext, primaryClient) + }) +} + +func checkConnectivity(t *testing.T, ctx environment.TestContext, client *api.Client) { + k8sClient := ctx.ControllerRuntimeClient(t) + + // On startup, the controller can take upwards of 1m to perform + // leader election so we may need to wait a long time for + // the reconcile loop to run (hence the 1m timeout here). + var gatewayAddress string + counter := &retry.Counter{Count: 600, Wait: 2 * time.Second} + retry.RunWith(counter, t, func(r *retry.R) { + var gateway gwv1beta1.Gateway + err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: "default"}, &gateway) + require.NoError(r, err) + + // check that we have an address to use + require.Len(r, gateway.Status.Addresses, 1) + // now we know we have an address, set it so we can use it + gatewayAddress = gateway.Status.Addresses[0].Value + }) + + targetAddress := fmt.Sprintf("http://%s/", gatewayAddress) + + logger.Log(t, "checking that the connection is not successful because there's no intention") + k8s.CheckStaticServerHTTPConnectionFailing(t, ctx.KubectlOptions(t), StaticClientName, targetAddress) + + logger.Log(t, "creating intention") + _, _, err := client.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ + Kind: api.ServiceIntentions, + Name: "static-server", + Sources: []*api.SourceIntention{ + { + Name: "gateway", + Action: api.IntentionActionAllow, + }, + }, + }, nil) + require.NoError(t, err) + defer func() { + _, err := client.ConfigEntries().Delete(api.ServiceIntentions, "static-server", &api.WriteOptions{}) + require.NoError(t, err) + }() + + logger.Log(t, "checking that connection is successful") + k8s.CheckStaticServerConnectionSuccessful(t, ctx.KubectlOptions(t), StaticClientName, targetAddress) +} diff --git a/control-plane/api-gateway/cache/consul.go b/control-plane/api-gateway/cache/consul.go index e47df71522..7737e80d57 100644 --- a/control-plane/api-gateway/cache/consul.go +++ b/control-plane/api-gateway/cache/consul.go @@ -17,6 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" "github.com/hashicorp/consul-k8s/control-plane/consul" "github.com/hashicorp/consul-k8s/control-plane/namespaces" "github.com/hashicorp/consul/api" @@ -60,6 +61,7 @@ type Config struct { ConsulClientConfig *consul.Config ConsulServerConnMgr consul.ServerConnectionManager NamespacesEnabled bool + Datacenter string CrossNamespaceACLPolicy string Logger logr.Logger } @@ -83,6 +85,8 @@ type Cache struct { synced chan struct{} kinds []string + + datacenter string } func New(config Config) *Cache { @@ -104,6 +108,7 @@ func New(config Config) *Cache { synced: make(chan struct{}, len(Kinds)), logger: config.Logger, crossNamespaceACLPolicy: config.CrossNamespaceACLPolicy, + datacenter: config.Datacenter, } } @@ -216,6 +221,19 @@ func (c *Cache) updateAndNotify(ctx context.Context, once *sync.Once, kind strin cache := common.NewReferenceMap() for _, entry := range entries { + meta := entry.GetMeta() + if meta[constants.MetaKeyKubeName] == "" || meta[constants.MetaKeyDatacenter] != c.datacenter { + // Don't process things that don't belong to us. The main reason + // for this is so that we don't garbage collect config entries that + // are either user-created or that another controller running in a + // federated datacenter creates. While we still allow for competing controllers + // syncing/overriding each other due to conflicting Kubernetes objects in + // two federated clusters (which is what the rest of the controllers also allow + // for), we don't want to delete a config entry just because we don't have + // its corresponding Kubernetes object if we know it belongs to another datacenter. + continue + } + cache.Set(common.EntryToReference(entry), entry) } @@ -336,6 +354,7 @@ func (c *Cache) ensureRole(client *api.Client) (string, error) { } aclRoleName := "managed-gateway-acl-role" + aclRole, _, err := client.ACL().RoleReadByName(aclRoleName, &api.QueryOptions{}) if err != nil { return "", err diff --git a/control-plane/api-gateway/cache/consul_test.go b/control-plane/api-gateway/cache/consul_test.go index 555e13b6c2..59570e532f 100644 --- a/control-plane/api-gateway/cache/consul_test.go +++ b/control-plane/api-gateway/cache/consul_test.go @@ -22,6 +22,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/event" "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" "github.com/hashicorp/consul-k8s/control-plane/consul" "github.com/hashicorp/consul-k8s/control-plane/helper/test" "github.com/hashicorp/consul/api" @@ -119,8 +120,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, })[api.HTTPRoute], args: args{ @@ -203,8 +206,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, })[api.HTTPRoute], }, @@ -291,8 +296,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, &api.HTTPRouteConfigEntry{ Kind: api.HTTPRoute, @@ -372,8 +379,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, })[api.HTTPRoute], args: args{ @@ -456,8 +465,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, })[api.HTTPRoute], }, @@ -540,8 +551,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, }, }, @@ -626,8 +639,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, })[api.HTTPRoute], args: args{ @@ -710,8 +725,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, &api.HTTPRouteConfigEntry{ Kind: api.HTTPRoute, @@ -791,8 +808,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, })[api.HTTPRoute], }, @@ -875,8 +894,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, }, }, @@ -962,8 +983,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, })[api.HTTPRoute], args: args{ @@ -1047,8 +1070,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, })[api.HTTPRoute], }, @@ -1132,8 +1157,10 @@ func Test_resourceCache_diff(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, }, }, }, @@ -1378,8 +1405,10 @@ func TestCache_Write(t *testing.T) { }, }, Hostnames: []string{"hostname.com"}, - Meta: map[string]string{}, - Status: api.ConfigEntryStatus{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, + Status: api.ConfigEntryStatus{}, } err = c.Write(context.Background(), entry) @@ -1410,18 +1439,24 @@ func TestCache_Get(t *testing.T) { want: &api.APIGatewayConfigEntry{ Kind: api.APIGateway, Name: "api-gw", - Meta: map[string]string{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, }, cache: loadedReferenceMaps([]api.ConfigEntry{ &api.APIGatewayConfigEntry{ Kind: api.APIGateway, Name: "api-gw", - Meta: map[string]string{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, }, &api.APIGatewayConfigEntry{ Kind: api.APIGateway, Name: "api-gw-2", - Meta: map[string]string{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, }, }), }, @@ -1438,12 +1473,16 @@ func TestCache_Get(t *testing.T) { &api.APIGatewayConfigEntry{ Kind: api.APIGateway, Name: "api-gw", - Meta: map[string]string{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, }, &api.APIGatewayConfigEntry{ Kind: api.APIGateway, Name: "api-gw-2", - Meta: map[string]string{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, }, }), }, @@ -1460,7 +1499,9 @@ func TestCache_Get(t *testing.T) { &api.HTTPRouteConfigEntry{ Kind: api.HTTPRoute, Name: "route", - Meta: map[string]string{}, + Meta: map[string]string{ + constants.MetaKeyKubeName: "name", + }, }, }), }, @@ -1766,7 +1807,8 @@ func setupHTTPRoutes() (*api.HTTPRouteConfigEntry, *api.HTTPRouteConfigEntry) { }, Hostnames: []string{"hostname.com"}, Meta: map[string]string{ - "metaKey": "metaVal", + "metaKey": "metaVal", + constants.MetaKeyKubeName: "name", }, Status: api.ConfigEntryStatus{}, } @@ -1849,7 +1891,8 @@ func setupHTTPRoutes() (*api.HTTPRouteConfigEntry, *api.HTTPRouteConfigEntry) { }, Hostnames: []string{"hostname.com"}, Meta: map[string]string{ - "metakey": "meta val", + "metakey": "meta val", + constants.MetaKeyKubeName: "name", }, } return routeOne, routeTwo @@ -1860,7 +1903,8 @@ func setupGateway() *api.APIGatewayConfigEntry { Kind: api.APIGateway, Name: "api-gw", Meta: map[string]string{ - "metakey": "meta val", + "metakey": "meta val", + constants.MetaKeyKubeName: "name", }, Listeners: []api.APIGatewayListener{ { @@ -1891,7 +1935,8 @@ func setupTCPRoute() *api.TCPRouteConfigEntry { }, }, Meta: map[string]string{ - "metakey": "meta val", + "metakey": "meta val", + constants.MetaKeyKubeName: "name", }, Status: api.ConfigEntryStatus{}, } @@ -1904,7 +1949,8 @@ func setupInlineCertificate() *api.InlineCertificateConfigEntry { Certificate: "cert", PrivateKey: "super secret", Meta: map[string]string{ - "metaKey": "meta val", + "metaKey": "meta val", + constants.MetaKeyKubeName: "name", }, } } diff --git a/control-plane/api-gateway/common/helm_config.go b/control-plane/api-gateway/common/helm_config.go index 2a6cc8211b..f0d4dc7988 100644 --- a/control-plane/api-gateway/common/helm_config.go +++ b/control-plane/api-gateway/common/helm_config.go @@ -3,7 +3,12 @@ package common -import "time" +import ( + "strings" + "time" +) + +const componentAuthMethod = "k8s-component-auth-method" // HelmConfig is the configuration of gateways that comes in from the user's Helm values. type HelmConfig struct { @@ -33,3 +38,20 @@ type ConsulConfig struct { HTTPPort int APITimeout time.Duration } + +func (h HelmConfig) Normalize() HelmConfig { + if h.AuthMethod != "" { + // strip off any DC naming off the back in case we're + // in a secondary DC, in which case our auth method is + // going to be a globally scoped auth method, and we want + // to target the locally scoped one, which is the auth + // method without the DC-specific suffix. + tokens := strings.Split(h.AuthMethod, componentAuthMethod) + if len(tokens) != 2 { + // skip the normalization if we can't do it. + return h + } + h.AuthMethod = tokens[0] + componentAuthMethod + } + return h +} diff --git a/control-plane/api-gateway/common/translation.go b/control-plane/api-gateway/common/translation.go index 5e577470d6..8644b64716 100644 --- a/control-plane/api-gateway/common/translation.go +++ b/control-plane/api-gateway/common/translation.go @@ -23,6 +23,7 @@ type ResourceTranslator struct { EnableK8sMirroring bool MirroringPrefix string ConsulPartition string + Datacenter string } func (t ResourceTranslator) NonNormalizedConfigEntryReference(kind string, id types.NamespacedName) api.ResourceReference { @@ -65,10 +66,10 @@ func (t ResourceTranslator) ToAPIGateway(gateway gwv1beta1.Gateway, resources *R Name: gateway.Name, Namespace: namespace, Partition: t.ConsulPartition, - Meta: map[string]string{ + Meta: t.addDatacenterToMeta(map[string]string{ constants.MetaKeyKubeNS: gateway.Namespace, constants.MetaKeyKubeName: gateway.Name, - }, + }), Listeners: listeners, } } @@ -128,10 +129,10 @@ func (t ResourceTranslator) ToHTTPRoute(route gwv1beta1.HTTPRoute, resources *Re Name: route.Name, Namespace: namespace, Partition: t.ConsulPartition, - Meta: map[string]string{ + Meta: t.addDatacenterToMeta(map[string]string{ constants.MetaKeyKubeNS: route.Namespace, constants.MetaKeyKubeName: route.Name, - }, + }), Hostnames: hostnames, Rules: rules, } @@ -292,10 +293,10 @@ func (t ResourceTranslator) ToTCPRoute(route gwv1alpha2.TCPRoute, resources *Res Name: route.Name, Namespace: namespace, Partition: t.ConsulPartition, - Meta: map[string]string{ + Meta: t.addDatacenterToMeta(map[string]string{ constants.MetaKeyKubeNS: route.Namespace, constants.MetaKeyKubeName: route.Name, - }, + }), Services: services, } } @@ -346,10 +347,10 @@ func (t ResourceTranslator) ToInlineCertificate(secret corev1.Secret) (*api.Inli Partition: t.ConsulPartition, Certificate: strings.TrimSpace(certificate), PrivateKey: strings.TrimSpace(privateKey), - Meta: map[string]string{ + Meta: t.addDatacenterToMeta(map[string]string{ constants.MetaKeyKubeNS: secret.Namespace, constants.MetaKeyKubeName: secret.Name, - }, + }), }, nil } @@ -361,3 +362,11 @@ func EntryToNamespacedName(entry api.ConfigEntry) types.NamespacedName { Name: meta[constants.MetaKeyKubeName], } } + +func (t ResourceTranslator) addDatacenterToMeta(meta map[string]string) map[string]string { + if t.Datacenter == "" { + return meta + } + meta[constants.MetaKeyDatacenter] = t.Datacenter + return meta +} diff --git a/control-plane/api-gateway/controllers/gateway_controller.go b/control-plane/api-gateway/controllers/gateway_controller.go index ec8c2e9af0..664bb98d3c 100644 --- a/control-plane/api-gateway/controllers/gateway_controller.go +++ b/control-plane/api-gateway/controllers/gateway_controller.go @@ -46,6 +46,7 @@ type GatewayControllerConfig struct { NamespacesEnabled bool CrossNamespaceACLPolicy string Partition string + Datacenter string AllowK8sNamespacesSet mapset.Set DenyK8sNamespacesSet mapset.Set } @@ -317,6 +318,7 @@ func SetupGatewayControllerWithManager(ctx context.Context, mgr ctrl.Manager, co ConsulClientConfig: config.ConsulClientConfig, ConsulServerConnMgr: config.ConsulServerConnMgr, NamespacesEnabled: config.NamespacesEnabled, + Datacenter: config.Datacenter, CrossNamespaceACLPolicy: config.CrossNamespaceACLPolicy, Logger: mgr.GetLogger(), } @@ -332,13 +334,14 @@ func SetupGatewayControllerWithManager(ctx context.Context, mgr ctrl.Manager, co r := &GatewayController{ Client: mgr.GetClient(), Log: mgr.GetLogger(), - HelmConfig: config.HelmConfig, + HelmConfig: config.HelmConfig.Normalize(), Translator: common.ResourceTranslator{ EnableConsulNamespaces: config.HelmConfig.EnableNamespaces, ConsulDestNamespace: config.HelmConfig.ConsulDestinationNamespace, EnableK8sMirroring: config.HelmConfig.EnableNamespaceMirroring, MirroringPrefix: config.HelmConfig.NamespaceMirroringPrefix, ConsulPartition: config.HelmConfig.ConsulPartition, + Datacenter: config.Datacenter, }, denyK8sNamespacesSet: config.DenyK8sNamespacesSet, allowK8sNamespacesSet: config.AllowK8sNamespacesSet, diff --git a/control-plane/api/v1alpha1/serviceresolver_types.go b/control-plane/api/v1alpha1/serviceresolver_types.go index 75aa44f6b9..d00821275d 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types.go +++ b/control-plane/api/v1alpha1/serviceresolver_types.go @@ -425,7 +425,7 @@ func (in *ServiceResolverRedirect) validate(path *field.Path, consulMeta common. "service resolver redirect cannot be empty")) } - if consulMeta.Partition != "default" && in.Datacenter != "" { + if consulMeta.Partition != "default" && consulMeta.Partition != "" && in.Datacenter != "" { errs = append(errs, field.Invalid(path.Child("datacenter"), in.Datacenter, "cross-datacenter redirect is only supported in the default partition")) } diff --git a/control-plane/connect-inject/constants/constants.go b/control-plane/connect-inject/constants/constants.go index 8987a9f5e8..0a341cd577 100644 --- a/control-plane/connect-inject/constants/constants.go +++ b/control-plane/connect-inject/constants/constants.go @@ -19,6 +19,9 @@ const ( // MetaKeyKubeName is the meta key name for Kubernetes object name used for a Consul object. MetaKeyKubeName = "k8s-name" + // MetaKeyDatacenter is the datacenter that this object was registered from. + MetaKeyDatacenter = "datacenter" + // MetaKeyKubeServiceName is the meta key name for Kubernetes service name used for the Consul services. MetaKeyKubeServiceName = "k8s-service-name" diff --git a/control-plane/subcommand/inject-connect/command.go b/control-plane/subcommand/inject-connect/command.go index a4fcf7c99d..6914894096 100644 --- a/control-plane/subcommand/inject-connect/command.go +++ b/control-plane/subcommand/inject-connect/command.go @@ -515,7 +515,9 @@ func (c *Command) Run(args []string) int { NamespacesEnabled: c.flagEnableNamespaces, CrossNamespaceACLPolicy: c.flagCrossNamespaceACLPolicy, Partition: c.consul.Partition, + Datacenter: c.consul.Datacenter, }) + if err != nil { setupLog.Error(err, "unable to create controller", "controller", "Gateway") return 1 From da147c1d7503e307ee4b93e0139a27a80a073cfc Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Fri, 9 Jun 2023 10:16:55 -0400 Subject: [PATCH 009/120] [API Gateway] fix dangling service registrations (#2321) * Fix when gateways are deleted before we get services populated into cache * a bit of cleanup --- control-plane/api-gateway/cache/gateway.go | 18 +++++++ .../controllers/gateway_controller.go | 50 +++++++++++++++---- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/control-plane/api-gateway/cache/gateway.go b/control-plane/api-gateway/cache/gateway.go index 846131d11e..d8dd37ffac 100644 --- a/control-plane/api-gateway/cache/gateway.go +++ b/control-plane/api-gateway/cache/gateway.go @@ -52,6 +52,24 @@ func (r *GatewayCache) ServicesFor(ref api.ResourceReference) []api.CatalogServi return r.data[common.NormalizeMeta(ref)] } +func (r *GatewayCache) FetchServicesFor(ctx context.Context, ref api.ResourceReference) ([]api.CatalogService, error) { + client, err := consul.NewClientFromConnMgr(r.config, r.serverMgr) + if err != nil { + return nil, err + } + + opts := &api.QueryOptions{} + if ref.Namespace != "" { + opts.Namespace = ref.Namespace + } + + services, _, err := client.Catalog().Service(ref.Name, "", opts.WithContext(ctx)) + if err != nil { + return nil, err + } + return common.DerefAll(services), nil +} + func (r *GatewayCache) EnsureSubscribed(ref api.ResourceReference, resource types.NamespacedName) { r.mutex.Lock() defer r.mutex.Unlock() diff --git a/control-plane/api-gateway/controllers/gateway_controller.go b/control-plane/api-gateway/controllers/gateway_controller.go index 664bb98d3c..f83466d67a 100644 --- a/control-plane/api-gateway/controllers/gateway_controller.go +++ b/control-plane/api-gateway/controllers/gateway_controller.go @@ -209,6 +209,12 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct return ctrl.Result{}, err } r.gatewayCache.RemoveSubscription(nonNormalizedConsulKey) + // make sure we have deregister all services even if they haven't + // hit cache yet + if err := r.deregisterAllServices(ctx, consulKey); err != nil { + log.Error(err, "error deregistering services") + return ctrl.Result{}, err + } } for _, deletion := range updates.Consul.Deletions { @@ -235,19 +241,24 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct } } - for _, registration := range updates.Consul.Registrations { - log.Info("registering service in Consul", "service", registration.Service.Service, "id", registration.Service.ID) - if err := r.cache.Register(ctx, registration); err != nil { - log.Error(err, "error registering service") - return ctrl.Result{}, err + if updates.UpsertGatewayDeployment { + // We only do some registration/deregistraion if we still have a valid gateway + // otherwise, we've already deregistered everything related to the gateway, so + // no need to do any of the following. + for _, registration := range updates.Consul.Registrations { + log.Info("registering service in Consul", "service", registration.Service.Service, "id", registration.Service.ID) + if err := r.cache.Register(ctx, registration); err != nil { + log.Error(err, "error registering service") + return ctrl.Result{}, err + } } - } - for _, deregistration := range updates.Consul.Deregistrations { - log.Info("deregistering service in Consul", "id", deregistration.ServiceID) - if err := r.cache.Deregister(ctx, deregistration); err != nil { - log.Error(err, "error deregistering service") - return ctrl.Result{}, err + for _, deregistration := range updates.Consul.Deregistrations { + log.Info("deregistering service in Consul", "id", deregistration.ServiceID) + if err := r.cache.Deregister(ctx, deregistration); err != nil { + log.Error(err, "error deregistering service") + return ctrl.Result{}, err + } } } @@ -270,6 +281,23 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct return ctrl.Result{}, nil } +func (r *GatewayController) deregisterAllServices(ctx context.Context, consulKey api.ResourceReference) error { + services, err := r.gatewayCache.FetchServicesFor(ctx, consulKey) + if err != nil { + return err + } + for _, service := range services { + if err := r.cache.Deregister(ctx, api.CatalogDeregistration{ + Node: service.Node, + ServiceID: service.ServiceID, + Namespace: service.Namespace, + }); err != nil { + return err + } + } + return nil +} + func (r *GatewayController) updateAndResetStatus(ctx context.Context, o client.Object) error { // we create a copy so that we can re-update its status if need be status := reflect.ValueOf(o.DeepCopyObject()).Elem().FieldByName("Status") From 198c4433d8927e2ec9c77b4a75ef80aa02f653ff Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Fri, 9 Jun 2023 10:36:03 -0400 Subject: [PATCH 010/120] api-gateway: add unit tests verifying scaling parameters on GatewayClassConfig are obeyed (#2272) * Add unit tests verifying that scaling parameters on GatewayClassConfig are obeyed * Add test case for scaling w/ no min or max configured --- .../api-gateway/gatekeeper/gatekeeper_test.go | 187 ++++++++++++++++++ 1 file changed, 187 insertions(+) diff --git a/control-plane/api-gateway/gatekeeper/gatekeeper_test.go b/control-plane/api-gateway/gatekeeper/gatekeeper_test.go index e2da61177f..ba58cb441f 100644 --- a/control-plane/api-gateway/gatekeeper/gatekeeper_test.go +++ b/control-plane/api-gateway/gatekeeper/gatekeeper_test.go @@ -210,6 +210,76 @@ func TestUpsert(t *testing.T) { }, }, }, + "create a new gateway where the GatewayClassConfig has a default number of instances greater than the max on the GatewayClassConfig": { + gateway: gwv1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: gwv1beta1.GatewaySpec{ + Listeners: listeners, + }, + }, + gatewayClassConfig: v1alpha1.GatewayClassConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "consul-gatewayclassconfig", + }, + Spec: v1alpha1.GatewayClassConfigSpec{ + DeploymentSpec: v1alpha1.DeploymentSpec{ + DefaultInstances: common.PointerTo(int32(8)), + MaxInstances: common.PointerTo(int32(5)), + MinInstances: common.PointerTo(int32(2)), + }, + CopyAnnotations: v1alpha1.CopyAnnotationsSpec{}, + ServiceType: (*corev1.ServiceType)(common.PointerTo("NodePort")), + }, + }, + helmConfig: common.HelmConfig{}, + initialResources: resources{}, + finalResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 5, nil, nil, "", "1"), + }, + roles: []*rbac.Role{}, + services: []*corev1.Service{}, + serviceAccounts: []*corev1.ServiceAccount{}, + }, + }, + "create a new gateway where the GatewayClassConfig has a default number of instances lesser than the min on the GatewayClassConfig": { + gateway: gwv1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: gwv1beta1.GatewaySpec{ + Listeners: listeners, + }, + }, + gatewayClassConfig: v1alpha1.GatewayClassConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "consul-gatewayclassconfig", + }, + Spec: v1alpha1.GatewayClassConfigSpec{ + DeploymentSpec: v1alpha1.DeploymentSpec{ + DefaultInstances: common.PointerTo(int32(1)), + MaxInstances: common.PointerTo(int32(5)), + MinInstances: common.PointerTo(int32(2)), + }, + CopyAnnotations: v1alpha1.CopyAnnotationsSpec{}, + ServiceType: (*corev1.ServiceType)(common.PointerTo("NodePort")), + }, + }, + helmConfig: common.HelmConfig{}, + initialResources: resources{}, + finalResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 2, nil, nil, "", "1"), + }, + roles: []*rbac.Role{}, + services: []*corev1.Service{}, + serviceAccounts: []*corev1.ServiceAccount{}, + }, + }, "update a gateway, adding a listener to a service": { gateway: gwv1beta1.Gateway{ ObjectMeta: metav1.ObjectMeta{ @@ -409,6 +479,123 @@ func TestUpsert(t *testing.T) { serviceAccounts: []*corev1.ServiceAccount{}, }, }, + "update a gateway deployment by scaling it when no min or max number of instances is defined on the GatewayClassConfig": { + gateway: gwv1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: gwv1beta1.GatewaySpec{ + Listeners: listeners, + }, + }, + gatewayClassConfig: v1alpha1.GatewayClassConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "consul-gatewayclassconfig", + }, + Spec: v1alpha1.GatewayClassConfigSpec{ + DeploymentSpec: v1alpha1.DeploymentSpec{ + DefaultInstances: common.PointerTo(int32(3)), + MaxInstances: nil, + MinInstances: nil, + }, + CopyAnnotations: v1alpha1.CopyAnnotationsSpec{}, + ServiceType: (*corev1.ServiceType)(common.PointerTo("NodePort")), + }, + }, + helmConfig: common.HelmConfig{}, + initialResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 8, nil, nil, "", "1"), + }, + }, + finalResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 8, nil, nil, "", "1"), + }, + roles: []*rbac.Role{}, + services: []*corev1.Service{}, + serviceAccounts: []*corev1.ServiceAccount{}, + }, + }, + "update a gateway deployment by scaling it lower than the min number of instances on the GatewayClassConfig": { + gateway: gwv1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: gwv1beta1.GatewaySpec{ + Listeners: listeners, + }, + }, + gatewayClassConfig: v1alpha1.GatewayClassConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "consul-gatewayclassconfig", + }, + Spec: v1alpha1.GatewayClassConfigSpec{ + DeploymentSpec: v1alpha1.DeploymentSpec{ + DefaultInstances: common.PointerTo(int32(3)), + MaxInstances: common.PointerTo(int32(5)), + MinInstances: common.PointerTo(int32(2)), + }, + CopyAnnotations: v1alpha1.CopyAnnotationsSpec{}, + ServiceType: (*corev1.ServiceType)(common.PointerTo("NodePort")), + }, + }, + helmConfig: common.HelmConfig{}, + initialResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 1, nil, nil, "", "1"), + }, + }, + finalResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 2, nil, nil, "", "1"), + }, + roles: []*rbac.Role{}, + services: []*corev1.Service{}, + serviceAccounts: []*corev1.ServiceAccount{}, + }, + }, + "update a gateway deployment by scaling it higher than the max number of instances on the GatewayClassConfig": { + gateway: gwv1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: gwv1beta1.GatewaySpec{ + Listeners: listeners, + }, + }, + gatewayClassConfig: v1alpha1.GatewayClassConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "consul-gatewayclassconfig", + }, + Spec: v1alpha1.GatewayClassConfigSpec{ + DeploymentSpec: v1alpha1.DeploymentSpec{ + DefaultInstances: common.PointerTo(int32(3)), + MaxInstances: common.PointerTo(int32(5)), + MinInstances: common.PointerTo(int32(2)), + }, + CopyAnnotations: v1alpha1.CopyAnnotationsSpec{}, + ServiceType: (*corev1.ServiceType)(common.PointerTo("NodePort")), + }, + }, + helmConfig: common.HelmConfig{}, + initialResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 10, nil, nil, "", "1"), + }, + }, + finalResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 5, nil, nil, "", "1"), + }, + roles: []*rbac.Role{}, + services: []*corev1.Service{}, + serviceAccounts: []*corev1.ServiceAccount{}, + }, + }, } for name, tc := range cases { From 8245efc1f3ccb26dd051126a876b293cb5c2e28f Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 9 Jun 2023 16:34:49 -0400 Subject: [PATCH 011/120] Rename GatewayClassController to prevent name collision (#2317) * Rename GatewayClassController to prevent name collision * Use gateway instead of gatewayclass in name * Use the constant in ownership checks * Change GatewayClass name to "consul" * Change GatewayClass name in cases * Change ApiGatewayClass back --- acceptance/tests/api-gateway/api_gateway_test.go | 2 +- .../fixtures/bases/api-gateway/gatewayclass.yaml | 2 +- .../cases/api-gateways/gateway/gateway.yaml | 4 ++-- charts/consul/templates/gateway-cleanup-job.yaml | 2 +- .../consul/templates/gateway-resources-job.yaml | 4 ++-- control-plane/api-gateway/common/constants.go | 2 ++ .../api-gateway/controllers/gateway_controller.go | 13 +++++++------ .../controllers/gatewayclass_controller.go | 2 -- .../controllers/gatewayclass_controller_test.go | 15 ++++++++------- ...roller.go => gatewayclassconfig_controller.go} | 0 ...t.go => gatewayclassconfig_controller_test.go} | 0 .../subcommand/inject-connect/command.go | 2 +- 12 files changed, 25 insertions(+), 23 deletions(-) rename control-plane/api-gateway/controllers/{gateway_class_config_controller.go => gatewayclassconfig_controller.go} (100%) rename control-plane/api-gateway/controllers/{gateway_class_config_controller_test.go => gatewayclassconfig_controller_test.go} (100%) diff --git a/acceptance/tests/api-gateway/api_gateway_test.go b/acceptance/tests/api-gateway/api_gateway_test.go index 17234cadf1..143b793bf8 100644 --- a/acceptance/tests/api-gateway/api_gateway_test.go +++ b/acceptance/tests/api-gateway/api_gateway_test.go @@ -27,7 +27,7 @@ import ( const ( StaticClientName = "static-client" - gatewayClassControllerName = "hashicorp.com/consul-api-gateway-controller" + gatewayClassControllerName = "consul.hashicorp.com/gateway-controller" gatewayClassFinalizer = "gateway-exists-finalizer.consul.hashicorp.com" gatewayFinalizer = "gateway-finalizer.consul.hashicorp.com" ) diff --git a/acceptance/tests/fixtures/bases/api-gateway/gatewayclass.yaml b/acceptance/tests/fixtures/bases/api-gateway/gatewayclass.yaml index 872faeb78c..9ff985fd49 100644 --- a/acceptance/tests/fixtures/bases/api-gateway/gatewayclass.yaml +++ b/acceptance/tests/fixtures/bases/api-gateway/gatewayclass.yaml @@ -6,7 +6,7 @@ kind: GatewayClass metadata: name: gateway-class spec: - controllerName: "hashicorp.com/consul-api-gateway-controller" + controllerName: "consul.hashicorp.com/gateway-controller" parametersRef: group: consul.hashicorp.com kind: GatewayClassConfig diff --git a/acceptance/tests/fixtures/cases/api-gateways/gateway/gateway.yaml b/acceptance/tests/fixtures/cases/api-gateways/gateway/gateway.yaml index 14c39978b7..7f0428b039 100644 --- a/acceptance/tests/fixtures/cases/api-gateways/gateway/gateway.yaml +++ b/acceptance/tests/fixtures/cases/api-gateways/gateway/gateway.yaml @@ -6,7 +6,7 @@ kind: Gateway metadata: name: gateway spec: - gatewayClassName: consul-api-gateway + gatewayClassName: consul listeners: - protocol: HTTPS port: 8080 @@ -17,4 +17,4 @@ spec: namespace: "default" allowedRoutes: namespaces: - from: "All" \ No newline at end of file + from: "All" diff --git a/charts/consul/templates/gateway-cleanup-job.yaml b/charts/consul/templates/gateway-cleanup-job.yaml index ff6f295357..44f032b5fd 100644 --- a/charts/consul/templates/gateway-cleanup-job.yaml +++ b/charts/consul/templates/gateway-cleanup-job.yaml @@ -41,7 +41,7 @@ spec: - consul-k8s-control-plane args: - gateway-cleanup - - -gateway-class-name=consul-api-gateway + - -gateway-class-name=consul - -gateway-class-config-name=consul-api-gateway resources: requests: diff --git a/charts/consul/templates/gateway-resources-job.yaml b/charts/consul/templates/gateway-resources-job.yaml index f8f92f799d..441e64eb14 100644 --- a/charts/consul/templates/gateway-resources-job.yaml +++ b/charts/consul/templates/gateway-resources-job.yaml @@ -41,9 +41,9 @@ spec: - consul-k8s-control-plane args: - gateway-resources - - -gateway-class-name=consul-api-gateway + - -gateway-class-name=consul - -gateway-class-config-name=consul-api-gateway - - -controller-name=hashicorp.com/consul-api-gateway-controller + - -controller-name=consul.hashicorp.com/gateway-controller - -app={{template "consul.name" .}} - -chart={{template "consul.chart" .}} - -heritage={{ .Release.Service }} diff --git a/control-plane/api-gateway/common/constants.go b/control-plane/api-gateway/common/constants.go index 68abfc96b1..c1ec0685a4 100644 --- a/control-plane/api-gateway/common/constants.go +++ b/control-plane/api-gateway/common/constants.go @@ -4,5 +4,7 @@ package common const ( + GatewayClassControllerName = "consul.hashicorp.com/gateway-controller" + AnnotationGatewayClassConfig = "consul.hashicorp.com/gateway-class-config" ) diff --git a/control-plane/api-gateway/controllers/gateway_controller.go b/control-plane/api-gateway/controllers/gateway_controller.go index f83466d67a..97805ccdfb 100644 --- a/control-plane/api-gateway/controllers/gateway_controller.go +++ b/control-plane/api-gateway/controllers/gateway_controller.go @@ -54,9 +54,10 @@ type GatewayControllerConfig struct { // GatewayController reconciles a Gateway object. // The Gateway is responsible for defining the behavior of API gateways. type GatewayController struct { - HelmConfig common.HelmConfig - Log logr.Logger - Translator common.ResourceTranslator + HelmConfig common.HelmConfig + Log logr.Logger + Translator common.ResourceTranslator + cache *cache.Cache gatewayCache *cache.GatewayCache allowK8sNamespacesSet mapset.Set @@ -174,7 +175,7 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct binder := binding.NewBinder(binding.BinderConfig{ Logger: log, Translator: r.Translator, - ControllerName: GatewayClassControllerName, + ControllerName: common.GatewayClassControllerName, Namespaces: namespaces, GatewayClassConfig: gatewayClassConfig, GatewayClass: gatewayClass, @@ -786,7 +787,7 @@ func (c *GatewayController) getConfigForGatewayClass(ctx context.Context, gatewa if ref := gatewayClassConfig.Spec.ParametersRef; ref != nil { if string(ref.Group) != v1alpha1.GroupVersion.Group || ref.Kind != v1alpha1.GatewayClassConfigKind || - gatewayClassConfig.Spec.ControllerName != GatewayClassControllerName { + gatewayClassConfig.Spec.ControllerName != common.GatewayClassControllerName { // we don't have supported params, so return nil return nil, nil } @@ -813,7 +814,7 @@ func (c *GatewayController) fetchControlledGateways(ctx context.Context, resourc list := gwv1beta1.GatewayClassList{} if err := c.Client.List(ctx, &list, &client.ListOptions{ - FieldSelector: fields.OneTermEqualSelector(GatewayClass_ControllerNameIndex, GatewayClassControllerName), + FieldSelector: fields.OneTermEqualSelector(GatewayClass_ControllerNameIndex, common.GatewayClassControllerName), }); err != nil { return err } diff --git a/control-plane/api-gateway/controllers/gatewayclass_controller.go b/control-plane/api-gateway/controllers/gatewayclass_controller.go index 4180157616..e37d1b3bcd 100644 --- a/control-plane/api-gateway/controllers/gatewayclass_controller.go +++ b/control-plane/api-gateway/controllers/gatewayclass_controller.go @@ -22,8 +22,6 @@ import ( ) const ( - GatewayClassControllerName = "hashicorp.com/consul-api-gateway-controller" - gatewayClassFinalizer = "gateway-exists-finalizer.consul.hashicorp.com" // GatewayClass status fields. diff --git a/control-plane/api-gateway/controllers/gatewayclass_controller_test.go b/control-plane/api-gateway/controllers/gatewayclass_controller_test.go index ac5be25205..0eeaf4c1de 100644 --- a/control-plane/api-gateway/controllers/gatewayclass_controller_test.go +++ b/control-plane/api-gateway/controllers/gatewayclass_controller_test.go @@ -22,6 +22,7 @@ import ( "sigs.k8s.io/gateway-api/apis/v1beta1" gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" ) @@ -57,7 +58,7 @@ func TestGatewayClassReconciler(t *testing.T) { Finalizers: []string{gatewayClassFinalizer}, }, Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: GatewayClassControllerName, + ControllerName: common.GatewayClassControllerName, }, }, expectedResult: ctrl.Result{}, @@ -81,7 +82,7 @@ func TestGatewayClassReconciler(t *testing.T) { Finalizers: []string{}, }, Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: GatewayClassControllerName, + ControllerName: common.GatewayClassControllerName, }, }, expectedResult: ctrl.Result{}, @@ -127,7 +128,7 @@ func TestGatewayClassReconciler(t *testing.T) { Finalizers: []string{gatewayClassFinalizer}, }, Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: GatewayClassControllerName, + ControllerName: common.GatewayClassControllerName, ParametersRef: &gwv1beta1.ParametersReference{ Kind: "some-nonsense", }, @@ -153,7 +154,7 @@ func TestGatewayClassReconciler(t *testing.T) { Finalizers: []string{gatewayClassFinalizer}, }, Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: GatewayClassControllerName, + ControllerName: common.GatewayClassControllerName, ParametersRef: &gwv1beta1.ParametersReference{ Kind: v1alpha1.GatewayClassConfigKind, Name: "does-not-exist", @@ -189,7 +190,7 @@ func TestGatewayClassReconciler(t *testing.T) { DeletionTimestamp: &deletionTimestamp, }, Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: GatewayClassControllerName, + ControllerName: common.GatewayClassControllerName, }, }, expectedResult: ctrl.Result{}, @@ -208,7 +209,7 @@ func TestGatewayClassReconciler(t *testing.T) { DeletionTimestamp: &deletionTimestamp, }, Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: GatewayClassControllerName, + ControllerName: common.GatewayClassControllerName, }, }, k8sObjects: []runtime.Object{ @@ -246,7 +247,7 @@ func TestGatewayClassReconciler(t *testing.T) { r := &GatewayClassController{ Client: fakeClient, - ControllerName: GatewayClassControllerName, + ControllerName: common.GatewayClassControllerName, Log: logrtest.New(t), } result, err := r.Reconcile(context.Background(), req) diff --git a/control-plane/api-gateway/controllers/gateway_class_config_controller.go b/control-plane/api-gateway/controllers/gatewayclassconfig_controller.go similarity index 100% rename from control-plane/api-gateway/controllers/gateway_class_config_controller.go rename to control-plane/api-gateway/controllers/gatewayclassconfig_controller.go diff --git a/control-plane/api-gateway/controllers/gateway_class_config_controller_test.go b/control-plane/api-gateway/controllers/gatewayclassconfig_controller_test.go similarity index 100% rename from control-plane/api-gateway/controllers/gateway_class_config_controller_test.go rename to control-plane/api-gateway/controllers/gatewayclassconfig_controller_test.go diff --git a/control-plane/subcommand/inject-connect/command.go b/control-plane/subcommand/inject-connect/command.go index 6914894096..8bada415db 100644 --- a/control-plane/subcommand/inject-connect/command.go +++ b/control-plane/subcommand/inject-connect/command.go @@ -476,7 +476,7 @@ func (c *Command) Run(args []string) int { } if err := (&gatewaycontrollers.GatewayClassController{ - ControllerName: gatewaycontrollers.GatewayClassControllerName, + ControllerName: gatewaycommon.GatewayClassControllerName, Client: mgr.GetClient(), Log: ctrl.Log.WithName("controllers").WithName("GatewayClass"), }).SetupWithManager(ctx, mgr); err != nil { From f07736b53f431f4c7956f5c69ac5b3de0fd4a481 Mon Sep 17 00:00:00 2001 From: Andrew Stucki Date: Fri, 9 Jun 2023 16:51:39 -0400 Subject: [PATCH 012/120] [API Gateway] Conformance Test Fixes (#2326) * Fix SupportedKinds array to be what Conformance test expects * Fix cert validation status condition for listeners * Add programmed condition for listeners * Fix unit test --------- Co-authored-by: Nathan Coleman --- control-plane/api-gateway/binding/binder.go | 14 +++++- .../api-gateway/binding/binder_test.go | 5 ++ control-plane/api-gateway/binding/result.go | 49 +++++++++++++++++-- .../api-gateway/binding/validation.go | 26 +++++++++- 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/control-plane/api-gateway/binding/binder.go b/control-plane/api-gateway/binding/binder.go index b677d69253..28a26985a8 100644 --- a/control-plane/api-gateway/binding/binder.go +++ b/control-plane/api-gateway/binding/binder.go @@ -214,7 +214,7 @@ func (b *Binder) Snapshot() *Snapshot { for i, listener := range b.config.Gateway.Spec.Listeners { status.Listeners = append(status.Listeners, gwv1beta1.ListenerStatus{ Name: listener.Name, - SupportedKinds: supportedKindsForProtocol[listener.Protocol], + SupportedKinds: supportedKinds(listener), AttachedRoutes: int32(boundCounts[listener.Name]), Conditions: listenerValidation.Conditions(b.config.Gateway.Generation, i), }) @@ -374,3 +374,15 @@ func addressesFromPodHosts(pods []corev1.Pod) []gwv1beta1.GatewayAddress { func isDeleted(object client.Object) bool { return !object.GetDeletionTimestamp().IsZero() } + +func supportedKinds(listener gwv1beta1.Listener) []gwv1beta1.RouteGroupKind { + if listener.AllowedRoutes != nil && listener.AllowedRoutes.Kinds != nil { + return common.Filter(listener.AllowedRoutes.Kinds, func(kind gwv1beta1.RouteGroupKind) bool { + if _, ok := allSupportedRouteKinds[kind.Kind]; !ok { + return true + } + return !common.NilOrEqual(kind.Group, gwv1beta1.GroupVersion.Group) + }) + } + return supportedKindsForProtocol[listener.Protocol] +} diff --git a/control-plane/api-gateway/binding/binder_test.go b/control-plane/api-gateway/binding/binder_test.go index 65cca94419..a3af702dab 100644 --- a/control-plane/api-gateway/binding/binder_test.go +++ b/control-plane/api-gateway/binding/binder_test.go @@ -233,6 +233,11 @@ func TestBinder_Lifecycle(t *testing.T) { Status: metav1.ConditionTrue, Reason: "Accepted", Message: "listener accepted", + }, { + Type: "Programmed", + Status: metav1.ConditionTrue, + Reason: "Programmed", + Message: "listener programmed", }, { Type: "Conflicted", Status: metav1.ConditionFalse, diff --git a/control-plane/api-gateway/binding/result.go b/control-plane/api-gateway/binding/result.go index dd82cd55b5..3ccb645c32 100644 --- a/control-plane/api-gateway/binding/result.go +++ b/control-plane/api-gateway/binding/result.go @@ -213,8 +213,8 @@ func (p parentBindResults) boundSections() mapset.Set { } var ( - // Each of the below are specified in the Gateway spec under ListenerConditionReason - // the general usage is that each error is specified as errListener* where * corresponds + // Each of the below are specified in the Gateway spec under ListenerConditionReason. + // The general usage is that each error is specified as errListener* where * corresponds // to the ListenerConditionReason given in the spec. If a reason is overloaded and can // be used with two different types of things (i.e. something is not found or it's not supported) // then we distinguish those two usages with errListener*_Usage. @@ -225,6 +225,8 @@ var ( errListenerInvalidCertificateRef_NotFound = errors.New("certificate not found") errListenerInvalidCertificateRef_NotSupported = errors.New("certificate type is not supported") errListenerInvalidCertificateRef_InvalidData = errors.New("certificate is invalid or does not contain a supported server name") + errListenerInvalidRouteKinds = errors.New("allowed route kind is invalid") + errListenerProgrammed_Invalid = errors.New("listener cannot be programmed because it is invalid") // Below is where any custom generic listener validation errors should go. // We map anything under here to a custom ListenerConditionReason of Invalid on @@ -243,7 +245,36 @@ type listenerValidationResult struct { conflictedErr error // status type: ResolvedRefs refErr error - // TODO: programmed + // status type: ResolvedRefs (but with internal validation) + routeKindErr error +} + +// programmedCondition constructs the condition for the Programmed status type. +// If there are no validation errors for the listener, we mark it as programmed. +// If there are validation errors for the listener, we mark it as invalid. +func (l listenerValidationResult) programmedCondition(generation int64) metav1.Condition { + now := timeFunc() + + switch { + case l.acceptedErr != nil, l.conflictedErr != nil, l.refErr != nil, l.routeKindErr != nil: + return metav1.Condition{ + Type: "Programmed", + Status: metav1.ConditionFalse, + Reason: "Invalid", + ObservedGeneration: generation, + Message: errListenerProgrammed_Invalid.Error(), + LastTransitionTime: now, + } + default: + return metav1.Condition{ + Type: "Programmed", + Status: metav1.ConditionTrue, + Reason: "Programmed", + ObservedGeneration: generation, + Message: "listener programmed", + LastTransitionTime: now, + } + } } // acceptedCondition constructs the condition for the Accepted status type. @@ -329,6 +360,17 @@ func (l listenerValidationResult) conflictedCondition(generation int64) metav1.C func (l listenerValidationResult) resolvedRefsCondition(generation int64) metav1.Condition { now := timeFunc() + if l.routeKindErr != nil { + return metav1.Condition{ + Type: "ResolvedRefs", + Status: metav1.ConditionFalse, + Reason: "InvalidRouteKinds", + ObservedGeneration: generation, + Message: l.routeKindErr.Error(), + LastTransitionTime: now, + } + } + switch l.refErr { case errListenerInvalidCertificateRef_NotFound, errListenerInvalidCertificateRef_NotSupported, errListenerInvalidCertificateRef_InvalidData: return metav1.Condition{ @@ -364,6 +406,7 @@ func (l listenerValidationResult) resolvedRefsCondition(generation int64) metav1 func (l listenerValidationResult) Conditions(generation int64) []metav1.Condition { return []metav1.Condition{ l.acceptedCondition(generation), + l.programmedCondition(generation), l.conflictedCondition(generation), l.resolvedRefsCondition(generation), } diff --git a/control-plane/api-gateway/binding/validation.go b/control-plane/api-gateway/binding/validation.go index 41c9484483..0e17e2b306 100644 --- a/control-plane/api-gateway/binding/validation.go +++ b/control-plane/api-gateway/binding/validation.go @@ -35,6 +35,10 @@ var ( Kind: "TCPRoute", }}, } + allSupportedRouteKinds = map[gwv1beta1.Kind]struct{}{ + gwv1beta1.Kind("HTTPRoute"): {}, + gwv1beta1.Kind("TCPRoute"): {}, + } ) // validateRefs validates backend references for a route, determining whether or @@ -202,7 +206,10 @@ func validateTLS(gateway gwv1beta1.Gateway, tls *gwv1beta1.GatewayTLSConfig, res func validateCertificateData(secret corev1.Secret) error { _, _, err := common.ParseCertificateData(secret) - return err + if err != nil { + return errListenerInvalidCertificateRef_InvalidData + } + return nil } // validateListeners validates the given listeners both internally and with respect to each @@ -231,6 +238,8 @@ func validateListeners(gateway gwv1beta1.Gateway, listeners []gwv1beta1.Listener } else if listener.Port == 20000 { //admin port result.acceptedErr = errListenerPortUnavailable } + + result.routeKindErr = validateListenerAllowedRouteKinds(listener.AllowedRoutes) } if err := merged[listener.Port].validateProtocol(); err != nil { @@ -244,6 +253,21 @@ func validateListeners(gateway gwv1beta1.Gateway, listeners []gwv1beta1.Listener return results } +func validateListenerAllowedRouteKinds(allowedRoutes *gwv1beta1.AllowedRoutes) error { + if allowedRoutes == nil { + return nil + } + for _, kind := range allowedRoutes.Kinds { + if _, ok := allSupportedRouteKinds[kind.Kind]; !ok { + return errListenerInvalidRouteKinds + } + if !common.NilOrEqual(kind.Group, gwv1beta1.GroupVersion.Group) { + return errListenerInvalidRouteKinds + } + } + return nil +} + // routeAllowedForListenerNamespaces determines whether the route is allowed // to bind to the Gateway based on the AllowedRoutes namespace selectors. func routeAllowedForListenerNamespaces(gatewayNamespace string, allowedRoutes *gwv1beta1.AllowedRoutes, namespace corev1.Namespace) bool { From 6933efec7fc2c05d4f6a2f7f3035c5b4bc0beb9f Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Fri, 9 Jun 2023 16:03:32 -0700 Subject: [PATCH 013/120] pin for 1.2.x-rc latest Consul submodules (#2327) --- acceptance/go.mod | 26 +++---- acceptance/go.sum | 56 ++++++++------ cli/go.mod | 57 +++++++------- cli/go.sum | 176 ++++++++++++++++--------------------------- control-plane/go.mod | 42 +++++------ control-plane/go.sum | 85 +++++++++++---------- 6 files changed, 209 insertions(+), 233 deletions(-) diff --git a/acceptance/go.mod b/acceptance/go.mod index e2221a09c0..ddce3e4e5c 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -4,14 +4,14 @@ go 1.20 require ( github.com/gruntwork-io/terratest v0.31.2 - github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230601034256-0c28b9b000cb - github.com/hashicorp/consul/api v1.10.1-0.20230530193107-04a0d0133ae4 - github.com/hashicorp/consul/sdk v0.13.1 + github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230609143603-198c4433d892 + github.com/hashicorp/consul/api v1.22.0-rc1 + github.com/hashicorp/consul/sdk v0.14.0-rc1 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.6.0 github.com/hashicorp/serf v0.10.1 github.com/hashicorp/vault/api v1.8.3 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.3 gopkg.in/yaml.v2 v2.4.0 k8s.io/api v0.26.3 k8s.io/apimachinery v0.26.3 @@ -29,11 +29,11 @@ require ( github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.14.1 // indirect github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -52,7 +52,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-bexpr v0.1.11 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.2.2 // indirect + github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.4.5 // indirect @@ -71,8 +71,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/miekg/dns v1.1.50 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect @@ -88,7 +88,7 @@ require ( github.com/oklog/run v1.0.0 // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pquerna/otp v1.2.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect @@ -102,10 +102,10 @@ require ( golang.org/x/crypto v0.1.0 // indirect golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.8.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.7.0 // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index 77a5b5875a..bd7421de60 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -141,8 +141,9 @@ github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7Do github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= @@ -182,8 +183,9 @@ github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -331,12 +333,12 @@ github.com/gruntwork-io/gruntwork-cli v0.7.0 h1:YgSAmfCj9c61H+zuvHwKfYUwlMhu5arn github.com/gruntwork-io/gruntwork-cli v0.7.0/go.mod h1:jp6Z7NcLF2avpY8v71fBx6hds9eOFPELSuD/VPv7w00= github.com/gruntwork-io/terratest v0.31.2 h1:xvYHA80MUq5kx670dM18HInewOrrQrAN+XbVVtytUHg= github.com/gruntwork-io/terratest v0.31.2/go.mod h1:EEgJie28gX/4AD71IFqgMj6e99KP5mi81hEtzmDjxTo= -github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230601034256-0c28b9b000cb h1:9GUvDoKVoV3IW78QyfoNY4bRcKxcn26wTGLoBrz92N4= -github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230601034256-0c28b9b000cb/go.mod h1:jKzTEgDc/np2gX/KPdfdm1mEUfZLrU8gc71XN3B15VI= -github.com/hashicorp/consul/api v1.10.1-0.20230530193107-04a0d0133ae4 h1:6kUTk+YBgA5X5b3gNAoI18WEK4/t75LcWSimEgmpFdg= -github.com/hashicorp/consul/api v1.10.1-0.20230530193107-04a0d0133ae4/go.mod h1:tXfrC6o0yFTgAW46xd5Ic8STHc9oIBcRVBcwhX5KNCQ= -github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= -github.com/hashicorp/consul/sdk v0.13.1/go.mod h1:SW/mM4LbKfqmMvcFu8v+eiQQ7oitXEFeiBe9StxERb0= +github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230609143603-198c4433d892 h1:4iI0ztWbVPTSDax+m1/XDs4jIRorxY4kSMyuM0fX+Dc= +github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230609143603-198c4433d892/go.mod h1:iZ8BJGSnY52wnxJTo2VIfGX63CPjqiNzbuqdOtJCKnI= +github.com/hashicorp/consul/api v1.22.0-rc1 h1:ePmGqndeMgaI38KUbSA/CqTzeEAIogXyWnfNJzglo70= +github.com/hashicorp/consul/api v1.22.0-rc1/go.mod h1:wtduXtbAqSGtBdi3tyA5SSAYGAG51rBejV9SEUBciMY= +github.com/hashicorp/consul/sdk v0.14.0-rc1 h1:PuETOfN0uxl28i0Pq6rK7TBCrIl7psMbL0YTSje4KvM= +github.com/hashicorp/consul/sdk v0.14.0-rc1/go.mod h1:gHYeuDa0+0qRAD6Wwr6yznMBvBwHKoxSBoW5l73+saE= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -347,13 +349,13 @@ github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.2.2 h1:ihRI7YFwcZdiSD7SIenIhHfQH3OuDvWerAUBZbeQS3M= -github.com/hashicorp/go-hclog v1.2.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -444,8 +446,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -462,15 +464,18 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= github.com/mattn/go-zglob v0.0.2-0.20190814121620-e3c945676326/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= @@ -547,8 +552,9 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= @@ -588,6 +594,7 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -636,8 +643,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -768,8 +775,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -790,7 +797,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -857,14 +864,15 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/cli/go.mod b/cli/go.mod index 9633fd5dd2..cdee871f38 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -5,19 +5,19 @@ go 1.20 require ( github.com/bgentry/speakeasy v0.1.0 github.com/cenkalti/backoff v2.2.1+incompatible - github.com/fatih/color v1.13.0 - github.com/google/go-cmp v0.5.8 + github.com/fatih/color v1.14.1 + github.com/google/go-cmp v0.5.9 github.com/hashicorp/consul-k8s/charts v0.0.0-00010101000000-000000000000 - github.com/hashicorp/consul/troubleshoot v0.1.2 - github.com/hashicorp/go-hclog v1.2.1 + github.com/hashicorp/consul/troubleshoot v0.3.0-rc1 + github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/hcp-sdk-go v0.23.1-0.20220921131124-49168300a7dc github.com/kr/text v0.2.0 - github.com/mattn/go-isatty v0.0.16 + github.com/mattn/go-isatty v0.0.17 github.com/mitchellh/cli v1.1.2 github.com/olekukonko/tablewriter v0.0.5 github.com/posener/complete v1.2.3 - github.com/stretchr/testify v1.8.0 - golang.org/x/text v0.7.0 + github.com/stretchr/testify v1.8.3 + golang.org/x/text v0.9.0 helm.sh/helm/v3 v3.9.4 k8s.io/api v0.25.0 k8s.io/apiextensions-apiserver v0.25.0 @@ -28,10 +28,11 @@ require ( sigs.k8s.io/yaml v1.3.0 ) -require go.opentelemetry.io/proto/otlp v0.11.0 // indirect +require go.opentelemetry.io/proto/otlp v0.19.0 // indirect require ( - cloud.google.com/go v0.99.0 // indirect + cloud.google.com/go/compute v1.19.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.27 // indirect @@ -49,14 +50,14 @@ require ( github.com/Masterminds/squirrel v1.5.3 // indirect github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect - github.com/armon/go-metrics v0.3.10 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 // indirect - github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc // indirect + github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195 // indirect github.com/containerd/containerd v1.6.6 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -68,8 +69,9 @@ require ( github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/emicklei/go-restful/v3 v3.8.0 // indirect - github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 // indirect - github.com/envoyproxy/protoc-gen-validate v0.9.1 // indirect + github.com/envoyproxy/go-control-plane v0.11.0 // indirect + github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e // indirect + github.com/envoyproxy/protoc-gen-validate v0.10.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect @@ -90,7 +92,7 @@ require ( github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.2.0 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/google/btree v1.0.1 // indirect github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -99,8 +101,8 @@ require ( github.com/gorilla/mux v1.8.0 // indirect github.com/gosuri/uitable v0.0.4 // indirect github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect - github.com/hashicorp/consul/api v1.20.0 // indirect - github.com/hashicorp/consul/envoyextensions v0.1.2 // indirect + github.com/hashicorp/consul/api v1.22.0-rc1 // indirect + github.com/hashicorp/consul/envoyextensions v0.3.0-rc1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect @@ -147,7 +149,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.12.2 // indirect - github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect github.com/rubenv/sql-migrate v1.1.1 // indirect @@ -165,16 +167,17 @@ require ( go.mongodb.org/mongo-driver v1.11.1 // indirect go.starlark.net v0.0.0-20230128213706-3f75dec8e403 // indirect golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect - golang.org/x/net v0.7.0 // indirect - golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 // indirect - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/term v0.5.0 // indirect + golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/oauth2 v0.6.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/term v0.8.0 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220921223823-23cae91e6737 // indirect - google.golang.org/grpc v1.49.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.55.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/cli/go.sum b/cli/go.sum index b5ee614f52..41b515d2e4 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -18,21 +18,16 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= +cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= @@ -104,8 +99,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= -github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= @@ -132,12 +127,13 @@ github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXe github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8= github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -153,10 +149,9 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc h1:PYXxkRUBGUMa5xgMVMDl62vEklZvKpVaxQeN9ie7Hfk= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195 h1:58f1tJ1ra+zFINPlwLWvQsR9CzAKt2e+EWV2yX9oXQ4= +github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= github.com/containerd/containerd v1.6.6 h1:xJNPhbrmz8xAMDNoVjHy9YHtWwEQNS+CDkcIRh7t8Y0= github.com/containerd/containerd v1.6.6/go.mod h1:ZoP1geJldzCVY3Tonoz7b1IXk8rIX0Nltt5QE4OMNk0= @@ -208,11 +203,13 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.11.0 h1:jtLewhRR2vMRNnq2ZZUoCjUlgut+Y0+sDDWPOfwOi1o= +github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e h1:g8euodkL4GdSpVAjfzhssb07KgVmOUqyF4QOmwFumTs= +github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e/go.mod h1:/NGEcKqwNq3HAS2vCqHfsPx9sJZbkiNQ6dGx9gTE/NA= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.9.1 h1:PS7VIOgmSVhWUEeZwTe7z7zouA22Cr590PzXKbZHOVY= -github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= +github.com/envoyproxy/protoc-gen-validate v0.10.0 h1:oIfnZFdC0YhpNNEX+SuIqko4cqqVZeN9IGTrhZje83Y= +github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -221,8 +218,9 @@ github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZM github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= @@ -336,6 +334,7 @@ github.com/golang-jwt/jwt/v4 v4.2.0 h1:besgBTC8w8HjP6NzQdxwKH9Z5oQMZ24ThTrHp3cZ8 github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -349,7 +348,6 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -366,10 +364,10 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= github.com/gomodule/redigo v1.8.2 h1:H5XSIre1MB5NbPYFp+i1NBbb5qN1W8Y8YAQoAYbkm8k= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -390,8 +388,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -399,7 +397,6 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -411,9 +408,6 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -423,8 +417,6 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= @@ -436,15 +428,16 @@ github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16 github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.20.0 h1:9IHTjNVSZ7MIwjlW3N3a7iGiykCMDpxZu8jsxFJh0yc= -github.com/hashicorp/consul/api v1.20.0/go.mod h1:nR64eD44KQ59Of/ECwt2vUmIK2DKsDzAwTmwmLl8Wpo= -github.com/hashicorp/consul/envoyextensions v0.1.2 h1:PvPqJ/td3UpOeIKQl5ycFPUy46XZP9awfhAUCduDeI4= -github.com/hashicorp/consul/envoyextensions v0.1.2/go.mod h1:N94DQQkgITiA40zuTQ/UdPOLAAWobgHfVT5u7wxE/aU= +github.com/hashicorp/consul/api v1.22.0-rc1 h1:ePmGqndeMgaI38KUbSA/CqTzeEAIogXyWnfNJzglo70= +github.com/hashicorp/consul/api v1.22.0-rc1/go.mod h1:wtduXtbAqSGtBdi3tyA5SSAYGAG51rBejV9SEUBciMY= +github.com/hashicorp/consul/envoyextensions v0.3.0-rc1 h1:weclrwjvLeX+vxPOyo4b4dCDxSpnDl60Z9K16nnCVnI= +github.com/hashicorp/consul/envoyextensions v0.3.0-rc1/go.mod h1:ckxoPHMiWXAe6dhyxmKsX1XqO4KTV64KWIyTu44z8UI= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= -github.com/hashicorp/consul/troubleshoot v0.1.2 h1:c6uMTSt/qTMhK3e18nl4xW4j7JcANdQNHOEYhoXH1P8= -github.com/hashicorp/consul/troubleshoot v0.1.2/go.mod h1:q35QOtN7K5kFLPm2SXHBDD+PzsuBekcqTZuuoOTzbWA= +github.com/hashicorp/consul/sdk v0.14.0-rc1 h1:PuETOfN0uxl28i0Pq6rK7TBCrIl7psMbL0YTSje4KvM= +github.com/hashicorp/consul/troubleshoot v0.3.0-rc1 h1:Z6ZUEKILsf85wA/zXK3XMop6IGtjui4ZZ0bAu+JIAz4= +github.com/hashicorp/consul/troubleshoot v0.3.0-rc1/go.mod h1:2WfcYZ8M4vpLtTv9M5Dp3egqSPZ16l5XsqMpO9QUYxc= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -452,8 +445,8 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v1.2.1 h1:YQsLlGDJgwhXFpucSPyVbCBviQtjlHv3jLTlp8YmtEw= -github.com/hashicorp/go-hclog v1.2.1/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -472,7 +465,7 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= @@ -582,8 +575,9 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= @@ -711,8 +705,9 @@ github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrb github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= @@ -779,8 +774,8 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -789,8 +784,9 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= @@ -835,8 +831,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= @@ -848,8 +844,8 @@ go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.11.0 h1:cLDgIBTf4lLOlztkhzAEdQsJ4Lj+i5Wc9k6Nn0K1VyU= -go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= go.starlark.net v0.0.0-20230128213706-3f75dec8e403 h1:jPeC7Exc+m8OBJUlWbBLh0O5UZPM7yU5W4adnhhbG4U= go.starlark.net v0.0.0-20230128213706-3f75dec8e403/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= @@ -889,6 +885,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= +golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -959,14 +957,13 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -980,12 +977,9 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1 h1:lxqLZaMad/dJHMFZH0NiNpiEZI/nhgWhe4wgzpE+MuA= -golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -998,8 +992,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1066,19 +1060,13 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1087,14 +1075,14 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1104,8 +1092,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1171,10 +1159,7 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= @@ -1204,15 +1189,6 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1262,27 +1238,11 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220921223823-23cae91e6737 h1:K1zaaMdYBXRyX+cwFnxj7M6zwDyumLQMZ5xqwGvjreQ= -google.golang.org/genproto v0.0.0-20220921223823-23cae91e6737/go.mod h1:2r/26NEF3bFmT3eC3aZreahSal0C3Shl8Gi6vyDYqOQ= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1303,15 +1263,11 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.49.0 h1:WTLtQzmQori5FUH25Pq4WT22oCsv8USpQ+F6rqtsmxw= -google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1325,8 +1281,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/control-plane/go.mod b/control-plane/go.mod index c916acb745..71396e2fd1 100644 --- a/control-plane/go.mod +++ b/control-plane/go.mod @@ -10,11 +10,11 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hashicorp/consul-k8s/control-plane/cni v0.0.0-20230511143918-bd16ab83383d github.com/hashicorp/consul-server-connection-manager v0.1.2 - github.com/hashicorp/consul/api v1.10.1-0.20230530193107-04a0d0133ae4 - github.com/hashicorp/consul/sdk v0.13.1 + github.com/hashicorp/consul/api v1.22.0-rc1 + github.com/hashicorp/consul/sdk v0.14.0-rc1 github.com/hashicorp/go-bexpr v0.1.11 github.com/hashicorp/go-discover v0.0.0-20230519164032-214571b6a530 - github.com/hashicorp/go-hclog v1.2.2 + github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-netaddrs v0.1.0 github.com/hashicorp/go-rootcerts v1.0.2 @@ -26,20 +26,20 @@ require ( github.com/mitchellh/cli v1.1.0 github.com/mitchellh/go-homedir v1.1.0 github.com/mitchellh/mapstructure v1.5.0 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.3 go.uber.org/zap v1.24.0 golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 golang.org/x/text v0.9.0 golang.org/x/time v0.3.0 gomodules.xyz/jsonpatch/v2 v2.3.0 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.26.1 - k8s.io/apimachinery v0.26.1 - k8s.io/client-go v0.26.1 - k8s.io/klog/v2 v2.90.1 + k8s.io/api v0.26.3 + k8s.io/apimachinery v0.26.3 + k8s.io/client-go v0.26.3 + k8s.io/klog/v2 v2.100.1 k8s.io/utils v0.0.0-20230209194617-a36077c30491 sigs.k8s.io/controller-runtime v0.14.6 - sigs.k8s.io/gateway-api v0.6.2 + sigs.k8s.io/gateway-api v0.7.1 ) require ( @@ -63,14 +63,14 @@ require ( github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 // indirect github.com/digitalocean/godo v1.7.5 // indirect github.com/dimchansky/utfbom v1.1.0 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.14.1 // indirect github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect github.com/go-logr/zapr v1.2.3 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect @@ -96,7 +96,7 @@ require ( github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect - github.com/hashicorp/go-uuid v1.0.2 // indirect + github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/mdns v1.0.4 // indirect @@ -110,8 +110,8 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/linode/linodego v0.7.1 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-testing-interface v1.0.0 // indirect @@ -125,7 +125,7 @@ require ( github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/posener/complete v1.2.3 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect @@ -145,11 +145,11 @@ require ( go.uber.org/multierr v1.6.0 // indirect golang.org/x/crypto v0.1.0 // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.8.0 // indirect + golang.org/x/net v0.10.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/term v0.6.0 // indirect + golang.org/x/sync v0.2.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/term v0.8.0 // indirect golang.org/x/tools v0.7.0 // indirect google.golang.org/api v0.30.0 // indirect google.golang.org/appengine v1.6.7 // indirect @@ -160,8 +160,8 @@ require ( gopkg.in/resty.v1 v1.12.0 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.26.1 // indirect - k8s.io/component-base v0.26.1 // indirect + k8s.io/apiextensions-apiserver v0.26.3 // indirect + k8s.io/component-base v0.26.3 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect diff --git a/control-plane/go.sum b/control-plane/go.sum index 3248aba347..2f7cbde2fc 100644 --- a/control-plane/go.sum +++ b/control-plane/go.sum @@ -113,8 +113,9 @@ github.com/containernetworking/cni v1.1.1 h1:ky20T7c0MvKvbMOwS/FrlbNwjEoqJEUUYfs github.com/containernetworking/cni v1.1.1/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o= @@ -140,8 +141,9 @@ github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= @@ -262,12 +264,12 @@ github.com/hashicorp/consul-k8s/control-plane/cni v0.0.0-20230511143918-bd16ab83 github.com/hashicorp/consul-k8s/control-plane/cni v0.0.0-20230511143918-bd16ab83383d/go.mod h1:IHIHMzkoMwlv6rLsgwcoFBVYupR7/1pKEOHBMjD4L0k= github.com/hashicorp/consul-server-connection-manager v0.1.2 h1:tNVQHUPuMbd+cMdD8kd+qkZUYpmLmrHMAV/49f4L53I= github.com/hashicorp/consul-server-connection-manager v0.1.2/go.mod h1:NzQoVi1KcxGI2SangsDue8+ZPuXZWs+6BKAKrDNyg+w= -github.com/hashicorp/consul/api v1.10.1-0.20230530193107-04a0d0133ae4 h1:6kUTk+YBgA5X5b3gNAoI18WEK4/t75LcWSimEgmpFdg= -github.com/hashicorp/consul/api v1.10.1-0.20230530193107-04a0d0133ae4/go.mod h1:tXfrC6o0yFTgAW46xd5Ic8STHc9oIBcRVBcwhX5KNCQ= +github.com/hashicorp/consul/api v1.22.0-rc1 h1:ePmGqndeMgaI38KUbSA/CqTzeEAIogXyWnfNJzglo70= +github.com/hashicorp/consul/api v1.22.0-rc1/go.mod h1:wtduXtbAqSGtBdi3tyA5SSAYGAG51rBejV9SEUBciMY= github.com/hashicorp/consul/proto-public v0.1.0 h1:O0LSmCqydZi363hsqc6n2v5sMz3usQMXZF6ziK3SzXU= github.com/hashicorp/consul/proto-public v0.1.0/go.mod h1:vs2KkuWwtjkIgA5ezp4YKPzQp4GitV+q/+PvksrA92k= -github.com/hashicorp/consul/sdk v0.13.1 h1:EygWVWWMczTzXGpO93awkHFzfUka6hLYJ0qhETd+6lY= -github.com/hashicorp/consul/sdk v0.13.1/go.mod h1:SW/mM4LbKfqmMvcFu8v+eiQQ7oitXEFeiBe9StxERb0= +github.com/hashicorp/consul/sdk v0.14.0-rc1 h1:PuETOfN0uxl28i0Pq6rK7TBCrIl7psMbL0YTSje4KvM= +github.com/hashicorp/consul/sdk v0.14.0-rc1/go.mod h1:gHYeuDa0+0qRAD6Wwr6yznMBvBwHKoxSBoW5l73+saE= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -280,13 +282,13 @@ github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/S github.com/hashicorp/go-discover v0.0.0-20230519164032-214571b6a530 h1:WUwSDou+memX/pb6xnjA0PfAqEEJtdWSrK00kl8ySK8= github.com/hashicorp/go-discover v0.0.0-20230519164032-214571b6a530/go.mod h1:RH2Jr1/cCsZ1nRLmAOC65hp/gRehf55SsUIYV2+NAxI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.2.2 h1:ihRI7YFwcZdiSD7SIenIhHfQH3OuDvWerAUBZbeQS3M= -github.com/hashicorp/go-hclog v1.2.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= +github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -313,8 +315,8 @@ github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjG github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= -github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -372,8 +374,8 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -386,14 +388,17 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= @@ -457,8 +462,9 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= @@ -495,6 +501,7 @@ github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 h1:Wdi9nwnhFNAlseAOe github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03/go.mod h1:gRAiPF5C5Nd0eyyRdqIu9qTiFSoZzpTq727b5B8fkkU= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= @@ -524,8 +531,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.480 h1:Dwnfdrk3KXpYRH9Kwrk9sHpZSOmrE7P9LBoNsYUJKR4= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.480/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.480 h1:YEDZmv2ABU8QvwXEVTOQgVEQzDOByhz73vdjL6sERkE= @@ -647,8 +655,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -669,8 +677,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -732,15 +740,16 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -939,18 +948,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ= -k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg= -k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI= -k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM= -k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ= -k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= -k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU= -k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE= -k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4= -k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU= -k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= -k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU= +k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE= +k8s.io/apiextensions-apiserver v0.26.3 h1:5PGMm3oEzdB1W/FTMgGIDmm100vn7IaUP5er36dB+YE= +k8s.io/apiextensions-apiserver v0.26.3/go.mod h1:jdA5MdjNWGP+njw1EKMZc64xAT5fIhN6VJrElV3sfpQ= +k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k= +k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s= +k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ= +k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g= +k8s.io/component-base v0.26.3/go.mod h1:5kj1kZYwSC6ZstHJN7oHBqcJC6yyn41eR+Sqa/mQc8E= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY= @@ -960,8 +969,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= -sigs.k8s.io/gateway-api v0.6.2 h1:583XHiX2M2bKEA0SAdkoxL1nY73W1+/M+IAm8LJvbEA= -sigs.k8s.io/gateway-api v0.6.2/go.mod h1:EYJT+jlPWTeNskjV0JTki/03WX1cyAnBhwBJfYHpV/0= +sigs.k8s.io/gateway-api v0.7.1 h1:Tts2jeepVkPA5rVG/iO+S43s9n7Vp7jCDhZDQYtPigQ= +sigs.k8s.io/gateway-api v0.7.1/go.mod h1:Xv0+ZMxX0lu1nSSDIIPEfbVztgNZ+3cfiYrJsa2Ooso= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= From 7f6e1cb5c4c2d8797944c1a3e0dcd12943f75138 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Fri, 9 Jun 2023 19:12:13 -0400 Subject: [PATCH 014/120] Ensure Reconciliation Stops (#2305) * first pass at halting: got httproute and api-gateway done * clean up test * Handle all set for infinite reconcile check * Add table tests for minimal setup * Added some odd field names to test normalization is handled correctly * Use funky casing http routes --- .../gateway_controller_integration_test.go | 1320 +++++++++++++++++ 1 file changed, 1320 insertions(+) create mode 100644 control-plane/api-gateway/controllers/gateway_controller_integration_test.go diff --git a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go new file mode 100644 index 0000000000..5dd5357d77 --- /dev/null +++ b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go @@ -0,0 +1,1320 @@ +package controllers + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "sync" + "testing" + "time" + + mapset "github.com/deckarep/golang-set" + logrtest "github.com/go-logr/logr/testr" + "github.com/stretchr/testify/require" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + + "github.com/hashicorp/consul-k8s/control-plane/api-gateway/cache" + "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" + "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" + "github.com/hashicorp/consul-k8s/control-plane/helper/test" + "github.com/hashicorp/consul/api" +) + +func TestControllerDoesNotInfinitelyReconcile(t *testing.T) { + s := runtime.NewScheme() + require.NoError(t, clientgoscheme.AddToScheme(s)) + require.NoError(t, gwv1alpha2.Install(s)) + require.NoError(t, gwv1beta1.Install(s)) + require.NoError(t, v1alpha1.AddToScheme(s)) + + testCases := map[string]struct { + namespace string + certFn func(*testing.T, context.Context, client.WithWatch, string) *corev1.Secret + gwFn func(*testing.T, context.Context, client.WithWatch, string) *gwv1beta1.Gateway + httpRouteFn func(*testing.T, context.Context, client.WithWatch, *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute + tcpRouteFn func(*testing.T, context.Context, client.WithWatch, *gwv1beta1.Gateway) *v1alpha2.TCPRoute + }{ + "all fields set": { + namespace: "consul", + certFn: createCert, + gwFn: createAllFieldsSetAPIGW, + httpRouteFn: createAllFieldsSetHTTPRoute, + tcpRouteFn: createAllFieldsSetTCPRoute, + }, + "minimal fields set": { + namespace: "", + certFn: createCert, + gwFn: minimalFieldsSetAPIGW, + httpRouteFn: minimalFieldsSetHTTPRoute, + tcpRouteFn: minimalFieldsSetTCPRoute, + }, + "funky casing to test normalization doesnt cause infinite reconciliation": { + namespace: "", + certFn: createCert, + gwFn: createFunkyCasingFieldsAPIGW, + httpRouteFn: createFunkyCasingFieldsHTTPRoute, + tcpRouteFn: createFunkyCasingFieldsTCPRoute, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + k8sClient := registerFieldIndexersForTest(fake.NewClientBuilder().WithScheme(s)).Build() + consulTestServerClient := test.TestServerWithMockConnMgrWatcher(t, nil) + ctx, cancel := context.WithCancel(context.Background()) + + t.Cleanup(func() { + cancel() + }) + logger := logrtest.New(t) + + cacheCfg := cache.Config{ + ConsulClientConfig: consulTestServerClient.Cfg, + ConsulServerConnMgr: consulTestServerClient.Watcher, + Logger: logger, + } + resourceCache := cache.New(cacheCfg) + + gwCache := cache.NewGatewayCache(ctx, cacheCfg) + + gwCtrl := GatewayController{ + HelmConfig: common.HelmConfig{}, + Log: logger, + Translator: common.ResourceTranslator{}, + cache: resourceCache, + gatewayCache: gwCache, + Client: k8sClient, + allowK8sNamespacesSet: mapset.NewSet(), + denyK8sNamespacesSet: mapset.NewSet(), + } + + go func() { + resourceCache.Run(ctx) + }() + + resourceCache.WaitSynced(ctx) + + gwSub := resourceCache.Subscribe(ctx, api.APIGateway, gwCtrl.transformConsulGateway) + httpRouteSub := resourceCache.Subscribe(ctx, api.HTTPRoute, gwCtrl.transformConsulHTTPRoute(ctx)) + tcpRouteSub := resourceCache.Subscribe(ctx, api.TCPRoute, gwCtrl.transformConsulTCPRoute(ctx)) + inlineCertSub := resourceCache.Subscribe(ctx, api.InlineCertificate, gwCtrl.transformConsulInlineCertificate(ctx)) + + cert := tc.certFn(t, ctx, k8sClient, tc.namespace) + k8sGWObj := tc.gwFn(t, ctx, k8sClient, tc.namespace) + + // reconcile so we add the finalizer + _, err := gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + Name: k8sGWObj.Name, + }, + }) + require.NoError(t, err) + + // reconcile again so that we get the creation with the finalizer + _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + Name: k8sGWObj.Name, + }, + }) + require.NoError(t, err) + + httpRouteObj := tc.httpRouteFn(t, ctx, k8sClient, k8sGWObj) + tcpRouteObj := tc.tcpRouteFn(t, ctx, k8sClient, k8sGWObj) + + // reconcile again so that we get the route bound to the gateway + _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + Name: k8sGWObj.Name, + }, + }) + require.NoError(t, err) + + // reconcile again so that we get the route bound to the gateway + _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + Name: k8sGWObj.Name, + }, + }) + require.NoError(t, err) + + wg := &sync.WaitGroup{} + // we never get the event from the cert because when it's created there are no gateways that reference it + wg.Add(3) + go func(w *sync.WaitGroup) { + gwDone := false + httpRouteDone := false + tcpRouteDone := false + for { + // get the creation events from the upsert and then continually read from channel so we dont block other subs + select { + case <-ctx.Done(): + return + case <-gwSub.Events(): + if !gwDone { + gwDone = true + wg.Done() + } + case <-httpRouteSub.Events(): + if !httpRouteDone { + httpRouteDone = true + wg.Done() + } + case <-tcpRouteSub.Events(): + if !tcpRouteDone { + tcpRouteDone = true + wg.Done() + } + case <-inlineCertSub.Events(): + } + } + }(wg) + + wg.Wait() + + gwNamespaceName := types.NamespacedName{ + Name: k8sGWObj.Name, + Namespace: k8sGWObj.Namespace, + } + + httpRouteNamespaceName := types.NamespacedName{ + Name: httpRouteObj.Name, + Namespace: httpRouteObj.Namespace, + } + + tcpRouteNamespaceName := types.NamespacedName{ + Name: tcpRouteObj.Name, + Namespace: tcpRouteObj.Namespace, + } + + certNamespaceName := types.NamespacedName{ + Name: cert.Name, + Namespace: cert.Namespace, + } + + gwRef := gwCtrl.Translator.ConfigEntryReference(api.APIGateway, gwNamespaceName) + httpRouteRef := gwCtrl.Translator.ConfigEntryReference(api.HTTPRoute, httpRouteNamespaceName) + tcpRouteRef := gwCtrl.Translator.ConfigEntryReference(api.TCPRoute, tcpRouteNamespaceName) + certRef := gwCtrl.Translator.ConfigEntryReference(api.InlineCertificate, certNamespaceName) + + curGWModifyIndex := resourceCache.Get(gwRef).GetModifyIndex() + curHTTPRouteModifyIndex := resourceCache.Get(httpRouteRef).GetModifyIndex() + curTCPRouteModifyIndex := resourceCache.Get(tcpRouteRef).GetModifyIndex() + curCertModifyIndex := resourceCache.Get(certRef).GetModifyIndex() + + err = k8sClient.Get(ctx, gwNamespaceName, k8sGWObj) + require.NoError(t, err) + curGWResourceVersion := k8sGWObj.ResourceVersion + + err = k8sClient.Get(ctx, httpRouteNamespaceName, httpRouteObj) + require.NoError(t, err) + curHTTPRouteResourceVersion := httpRouteObj.ResourceVersion + + err = k8sClient.Get(ctx, tcpRouteNamespaceName, tcpRouteObj) + require.NoError(t, err) + curTCPRouteResourceVersion := tcpRouteObj.ResourceVersion + + err = k8sClient.Get(ctx, certNamespaceName, cert) + require.NoError(t, err) + curCertResourceVersion := cert.ResourceVersion + + go func() { + // reconcile multiple times with no changes to be sure + for i := 0; i < 5; i++ { + _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + }, + }) + require.NoError(t, err) + } + }() + + require.Never(t, func() bool { + err = k8sClient.Get(ctx, gwNamespaceName, k8sGWObj) + require.NoError(t, err) + newGWResourceVersion := k8sGWObj.ResourceVersion + + err = k8sClient.Get(ctx, httpRouteNamespaceName, httpRouteObj) + require.NoError(t, err) + newHTTPRouteResourceVersion := httpRouteObj.ResourceVersion + + err = k8sClient.Get(ctx, tcpRouteNamespaceName, tcpRouteObj) + require.NoError(t, err) + newTCPRouteResourceVersion := tcpRouteObj.ResourceVersion + + err = k8sClient.Get(ctx, certNamespaceName, cert) + require.NoError(t, err) + newCertResourceVersion := cert.ResourceVersion + + return curGWModifyIndex == resourceCache.Get(gwRef).GetModifyIndex() && + curGWResourceVersion == newGWResourceVersion && + curHTTPRouteModifyIndex == resourceCache.Get(httpRouteRef).GetModifyIndex() && + curHTTPRouteResourceVersion == newHTTPRouteResourceVersion && + curTCPRouteModifyIndex == resourceCache.Get(tcpRouteRef).GetModifyIndex() && + curTCPRouteResourceVersion == newTCPRouteResourceVersion && + curCertModifyIndex == resourceCache.Get(certRef).GetModifyIndex() && + curCertResourceVersion == newCertResourceVersion + }, time.Duration(2*time.Second), time.Duration(500*time.Millisecond), fmt.Sprintf("curGWModifyIndex: %d, newIndx: %d", curGWModifyIndex, resourceCache.Get(gwRef).GetModifyIndex()), + ) + }) + } +} + +func createAllFieldsSetAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { + // listener one configuration + listenerOneName := "listener-one" + listenerOneHostname := "*.consul.io" + listenerOnePort := 3366 + listenerOneProtocol := "https" + + // listener two configuration + listenerTwoName := "listener-two" + listenerTwoHostname := "*.consul.io" + listenerTwoPort := 5432 + listenerTwoProtocol := "http" + + // listener three configuration + listenerThreeName := "listener-three" + listenerThreePort := 8081 + listenerThreeProtocol := "tcp" + + // listener four configuration + listenerFourName := "listener-four" + listenerFourHostname := "*.consul.io" + listenerFourPort := 5433 + listenerFourProtocol := "http" + + // Write gw to k8s + gwClassCfg := &v1alpha1.GatewayClassConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClassConfig", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gateway-class-config", + }, + Spec: v1alpha1.GatewayClassConfigSpec{}, + } + gwClass := &gwv1beta1.GatewayClass{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClass", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gatewayclass", + }, + Spec: gwv1beta1.GatewayClassSpec{ + ControllerName: "hashicorp.com/consul-api-gateway-controller", + ParametersRef: &gwv1beta1.ParametersReference{ + Group: "consul.hashicorp.com", + Kind: "GatewayClassConfig", + Name: "gateway-class-config", + }, + Description: new(string), + }, + } + gw := &gwv1beta1.Gateway{ + TypeMeta: metav1.TypeMeta{ + Kind: "Gateway", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gw", + Namespace: namespace, + Annotations: make(map[string]string), + }, + Spec: gwv1beta1.GatewaySpec{ + GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), + Listeners: []gwv1beta1.Listener{ + { + Name: gwv1beta1.SectionName(listenerOneName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), + Port: gwv1beta1.PortNumber(listenerOnePort), + Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), + TLS: &gwv1beta1.GatewayTLSConfig{ + CertificateRefs: []gwv1beta1.SecretObjectReference{ + { + Kind: common.PointerTo(gwv1beta1.Kind("Secret")), + Name: gwv1beta1.ObjectName("one-cert"), + Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), + }, + }, + }, + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerTwoName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerTwoHostname)), + Port: gwv1beta1.PortNumber(listenerTwoPort), + Protocol: gwv1beta1.ProtocolType(listenerTwoProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("Same")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerThreeName), + Port: gwv1beta1.PortNumber(listenerThreePort), + Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerFourName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerFourHostname)), + Port: gwv1beta1.PortNumber(listenerFourPort), + Protocol: gwv1beta1.ProtocolType(listenerFourProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("Selector")), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.NamespaceNameLabel: "consul", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, gwClassCfg) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gwClass) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gw) + require.NoError(t, err) + + return gw +} + +func createAllFieldsSetHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { + svcDefault := &v1alpha1.ServiceDefaults{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceDefaults", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + Spec: v1alpha1.ServiceDefaultsSpec{ + Protocol: "http", + }, + } + + svc := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "high", + Protocol: "TCP", + Port: 8080, + }, + }, + Selector: map[string]string{"app": "Service"}, + }, + } + + serviceAccount := &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceAccount", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + } + + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: common.PointerTo(int32(1)), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "Service"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{}, + }, + }, + } + + err := k8sClient.Create(ctx, svcDefault) + require.NoError(t, err) + + err = k8sClient.Create(ctx, svc) + require.NoError(t, err) + + err = k8sClient.Create(ctx, serviceAccount) + require.NoError(t, err) + + err = k8sClient.Create(ctx, deployment) + require.NoError(t, err) + + route := &gwv1beta1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "HTTPRoute", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "http-route", + }, + Spec: gwv1beta1.HTTPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Kind: (*gwv1beta1.Kind)(&gw.Kind), + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[0].Name, + Port: &gw.Spec.Listeners[0].Port, + }, + }, + }, + Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, + Rules: []gwv1beta1.HTTPRouteRule{ + { + Matches: []gwv1beta1.HTTPRouteMatch{ + { + Path: &gwv1beta1.HTTPPathMatch{ + Type: common.PointerTo(gwv1beta1.PathMatchType("PathPrefix")), + Value: common.PointerTo("/v1"), + }, + Headers: []gwv1beta1.HTTPHeaderMatch{ + { + Type: common.PointerTo(gwv1beta1.HeaderMatchExact), + Name: "version", + Value: "version", + }, + }, + QueryParams: []gwv1beta1.HTTPQueryParamMatch{ + { + Type: common.PointerTo(gwv1beta1.QueryParamMatchExact), + Name: "search", + Value: "q", + }, + }, + Method: common.PointerTo(gwv1beta1.HTTPMethod("GET")), + }, + }, + Filters: []gwv1beta1.HTTPRouteFilter{ + { + Type: gwv1beta1.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gwv1beta1.HTTPHeaderFilter{ + Set: []gwv1beta1.HTTPHeader{ + { + Name: "foo", + Value: "bax", + }, + }, + Add: []gwv1beta1.HTTPHeader{ + { + Name: "arc", + Value: "reactor", + }, + }, + Remove: []string{"remove"}, + }, + }, + { + Type: gwv1beta1.HTTPRouteFilterURLRewrite, + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ + Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), + Path: &gwv1beta1.HTTPPathModifier{ + Type: gwv1beta1.FullPathHTTPPathModifier, + ReplaceFullPath: common.PointerTo("/foobar"), + }, + }, + }, + + { + Type: gwv1beta1.HTTPRouteFilterURLRewrite, + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ + Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), + Path: &gwv1beta1.HTTPPathModifier{ + Type: gwv1beta1.PrefixMatchHTTPPathModifier, + ReplacePrefixMatch: common.PointerTo("/foo"), + }, + }, + }, + }, + BackendRefs: []gwv1beta1.HTTPBackendRef{ + { + BackendRef: gwv1beta1.BackendRef{ + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(8080)), + }, + Weight: common.PointerTo(int32(50)), + }, + }, + }, + }, + }, + }, + } + + err = k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func createAllFieldsSetTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { + route := &v1alpha2.TCPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "TCPRoute", + APIVersion: "gateway.networking.k8s.io/v1alpha2", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "tcp-route", + }, + Spec: gwv1alpha2.TCPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Kind: (*gwv1beta1.Kind)(&gw.Kind), + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[2].Name, + Port: &gw.Spec.Listeners[2].Port, + }, + }, + }, + Rules: []gwv1alpha2.TCPRouteRule{ + { + BackendRefs: []gwv1beta1.BackendRef{ + { + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(25000)), + }, + Weight: common.PointerTo(int32(50)), + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func createCert(t *testing.T, ctx context.Context, k8sClient client.WithWatch, certNS string) *corev1.Secret { + // listener one tls config + certName := "one-cert" + + privateKey, err := rsa.GenerateKey(rand.Reader, 1024) + require.NoError(t, err) + + usage := x509.KeyUsageCertSign + expiration := time.Now().AddDate(10, 0, 0) + + cert := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + CommonName: "consul.test", + }, + IsCA: true, + NotBefore: time.Now().Add(-10 * time.Minute), + NotAfter: expiration, + SubjectKeyId: []byte{1, 2, 3, 4, 6}, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + KeyUsage: usage, + BasicConstraintsValid: true, + } + caCert := cert + caPrivateKey := privateKey + + data, err := x509.CreateCertificate(rand.Reader, cert, caCert, &privateKey.PublicKey, caPrivateKey) + require.NoError(t, err) + + certBytes := pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: data, + }) + + privateKeyBytes := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(privateKey), + }) + + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: certNS, + Name: certName, + }, + Data: map[string][]byte{ + corev1.TLSCertKey: certBytes, + corev1.TLSPrivateKeyKey: privateKeyBytes, + }, + } + + err = k8sClient.Create(ctx, secret) + require.NoError(t, err) + + return secret +} + +func minimalFieldsSetAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { + // listener one configuration + listenerOneName := "listener-one" + listenerOneHostname := "*.consul.io" + listenerOnePort := 3366 + listenerOneProtocol := "https" + + // listener three configuration + listenerThreeName := "listener-three" + listenerThreePort := 8081 + listenerThreeProtocol := "tcp" + + // Write gw to k8s + gwClassCfg := &v1alpha1.GatewayClassConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClassConfig", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gateway-class-config", + }, + Spec: v1alpha1.GatewayClassConfigSpec{}, + } + gwClass := &gwv1beta1.GatewayClass{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClass", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gatewayclass", + }, + Spec: gwv1beta1.GatewayClassSpec{ + ControllerName: "hashicorp.com/consul-api-gateway-controller", + ParametersRef: &gwv1beta1.ParametersReference{ + Group: "consul.hashicorp.com", + Kind: "GatewayClassConfig", + Name: "gateway-class-config", + }, + Description: new(string), + }, + } + gw := &gwv1beta1.Gateway{ + TypeMeta: metav1.TypeMeta{ + Kind: "Gateway", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gw", + Annotations: make(map[string]string), + }, + Spec: gwv1beta1.GatewaySpec{ + GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), + Listeners: []gwv1beta1.Listener{ + { + Name: gwv1beta1.SectionName(listenerOneName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), + Port: gwv1beta1.PortNumber(listenerOnePort), + Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), + TLS: &gwv1beta1.GatewayTLSConfig{ + CertificateRefs: []gwv1beta1.SecretObjectReference{ + { + Kind: common.PointerTo(gwv1beta1.Kind("Secret")), + Name: gwv1beta1.ObjectName("one-cert"), + Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), + }, + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerThreeName), + Port: gwv1beta1.PortNumber(listenerThreePort), + Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, gwClassCfg) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gwClass) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gw) + require.NoError(t, err) + + return gw +} + +func minimalFieldsSetHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { + svcDefault := &v1alpha1.ServiceDefaults{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceDefaults", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + Spec: v1alpha1.ServiceDefaultsSpec{ + Protocol: "http", + }, + } + + svc := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "high", + Protocol: "TCP", + Port: 8080, + }, + }, + Selector: map[string]string{"app": "Service"}, + }, + } + + serviceAccount := &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceAccount", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + } + + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: common.PointerTo(int32(1)), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "Service"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{}, + }, + }, + } + + err := k8sClient.Create(ctx, svcDefault) + require.NoError(t, err) + + err = k8sClient.Create(ctx, svc) + require.NoError(t, err) + + err = k8sClient.Create(ctx, serviceAccount) + require.NoError(t, err) + + err = k8sClient.Create(ctx, deployment) + require.NoError(t, err) + + route := &gwv1beta1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "HTTPRoute", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "http-route", + }, + Spec: gwv1beta1.HTTPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Kind: (*gwv1beta1.Kind)(&gw.Kind), + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[0].Name, + Port: &gw.Spec.Listeners[0].Port, + }, + }, + }, + Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, + Rules: []gwv1beta1.HTTPRouteRule{ + { + BackendRefs: []gwv1beta1.HTTPBackendRef{ + { + BackendRef: gwv1beta1.BackendRef{ + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(8080)), + }, + }, + }, + }, + }, + }, + }, + } + + err = k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func minimalFieldsSetTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { + route := &v1alpha2.TCPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "TCPRoute", + APIVersion: "gateway.networking.k8s.io/v1alpha2", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "tcp-route", + }, + Spec: gwv1alpha2.TCPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Kind: (*gwv1beta1.Kind)(&gw.Kind), + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[1].Name, + Port: &gw.Spec.Listeners[1].Port, + }, + }, + }, + Rules: []gwv1alpha2.TCPRouteRule{ + { + BackendRefs: []gwv1beta1.BackendRef{ + { + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(25000)), + }, + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func createFunkyCasingFieldsAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { + // listener one configuration + listenerOneName := "listener-one" + listenerOneHostname := "*.consul.io" + listenerOnePort := 3366 + listenerOneProtocol := "hTtPs" + + // listener two configuration + listenerTwoName := "listener-two" + listenerTwoHostname := "*.consul.io" + listenerTwoPort := 5432 + listenerTwoProtocol := "HTTP" + + // listener three configuration + listenerThreeName := "listener-three" + listenerThreePort := 8081 + listenerThreeProtocol := "tCp" + + // listener four configuration + listenerFourName := "listener-four" + listenerFourHostname := "*.consul.io" + listenerFourPort := 5433 + listenerFourProtocol := "hTTp" + + // Write gw to k8s + gwClassCfg := &v1alpha1.GatewayClassConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClassConfig", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gateway-class-config", + }, + Spec: v1alpha1.GatewayClassConfigSpec{}, + } + gwClass := &gwv1beta1.GatewayClass{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClass", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gatewayclass", + }, + Spec: gwv1beta1.GatewayClassSpec{ + ControllerName: "hashicorp.com/consul-api-gateway-controller", + ParametersRef: &gwv1beta1.ParametersReference{ + Group: "consul.hashicorp.com", + Kind: "GatewayClassConfig", + Name: "gateway-class-config", + }, + Description: new(string), + }, + } + gw := &gwv1beta1.Gateway{ + TypeMeta: metav1.TypeMeta{ + Kind: "Gateway", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gw", + Namespace: namespace, + Annotations: make(map[string]string), + }, + Spec: gwv1beta1.GatewaySpec{ + GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), + Listeners: []gwv1beta1.Listener{ + { + Name: gwv1beta1.SectionName(listenerOneName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), + Port: gwv1beta1.PortNumber(listenerOnePort), + Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), + TLS: &gwv1beta1.GatewayTLSConfig{ + CertificateRefs: []gwv1beta1.SecretObjectReference{ + { + Kind: common.PointerTo(gwv1beta1.Kind("Secret")), + Name: gwv1beta1.ObjectName("one-cert"), + Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), + }, + }, + }, + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerTwoName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerTwoHostname)), + Port: gwv1beta1.PortNumber(listenerTwoPort), + Protocol: gwv1beta1.ProtocolType(listenerTwoProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("Same")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerThreeName), + Port: gwv1beta1.PortNumber(listenerThreePort), + Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerFourName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerFourHostname)), + Port: gwv1beta1.PortNumber(listenerFourPort), + Protocol: gwv1beta1.ProtocolType(listenerFourProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("Selector")), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.NamespaceNameLabel: "consul", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, gwClassCfg) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gwClass) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gw) + require.NoError(t, err) + + return gw +} + +func createFunkyCasingFieldsHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { + svcDefault := &v1alpha1.ServiceDefaults{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceDefaults", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + Spec: v1alpha1.ServiceDefaultsSpec{ + Protocol: "hTtp", + }, + } + + svc := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "high", + Protocol: "TCP", + Port: 8080, + }, + }, + Selector: map[string]string{"app": "Service"}, + }, + } + + serviceAccount := &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceAccount", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + } + + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: common.PointerTo(int32(1)), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "Service"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{}, + }, + }, + } + + err := k8sClient.Create(ctx, svcDefault) + require.NoError(t, err) + + err = k8sClient.Create(ctx, svc) + require.NoError(t, err) + + err = k8sClient.Create(ctx, serviceAccount) + require.NoError(t, err) + + err = k8sClient.Create(ctx, deployment) + require.NoError(t, err) + + route := &gwv1beta1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "HTTPRoute", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "http-route", + }, + Spec: gwv1beta1.HTTPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[0].Name, + Port: &gw.Spec.Listeners[0].Port, + }, + }, + }, + Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, + Rules: []gwv1beta1.HTTPRouteRule{ + { + Matches: []gwv1beta1.HTTPRouteMatch{ + { + Path: &gwv1beta1.HTTPPathMatch{ + Type: common.PointerTo(gwv1beta1.PathMatchPathPrefix), + }, + Headers: []gwv1beta1.HTTPHeaderMatch{ + { + Type: common.PointerTo(gwv1beta1.HeaderMatchExact), + Name: "version", + Value: "version", + }, + }, + QueryParams: []gwv1beta1.HTTPQueryParamMatch{ + { + Type: common.PointerTo(gwv1beta1.QueryParamMatchExact), + Name: "search", + Value: "q", + }, + }, + Method: common.PointerTo(gwv1beta1.HTTPMethod("geT")), + }, + }, + Filters: []gwv1beta1.HTTPRouteFilter{ + { + Type: gwv1beta1.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gwv1beta1.HTTPHeaderFilter{ + Set: []gwv1beta1.HTTPHeader{ + { + Name: "foo", + Value: "bax", + }, + }, + Add: []gwv1beta1.HTTPHeader{ + { + Name: "arc", + Value: "reactor", + }, + }, + Remove: []string{"remove"}, + }, + }, + { + Type: gwv1beta1.HTTPRouteFilterURLRewrite, + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ + Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), + Path: &gwv1beta1.HTTPPathModifier{ + Type: gwv1beta1.FullPathHTTPPathModifier, + ReplaceFullPath: common.PointerTo("/foobar"), + }, + }, + }, + + { + Type: gwv1beta1.HTTPRouteFilterURLRewrite, + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ + Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), + Path: &gwv1beta1.HTTPPathModifier{ + Type: gwv1beta1.PrefixMatchHTTPPathModifier, + ReplacePrefixMatch: common.PointerTo("/foo"), + }, + }, + }, + }, + BackendRefs: []gwv1beta1.HTTPBackendRef{ + { + BackendRef: gwv1beta1.BackendRef{ + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(8080)), + }, + Weight: common.PointerTo(int32(-50)), + }, + }, + }, + }, + }, + }, + } + + err = k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func createFunkyCasingFieldsTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { + route := &v1alpha2.TCPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "TCPRoute", + APIVersion: "gateway.networking.k8s.io/v1alpha2", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "tcp-route", + }, + Spec: gwv1alpha2.TCPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[2].Name, + Port: &gw.Spec.Listeners[2].Port, + }, + }, + }, + Rules: []gwv1alpha2.TCPRouteRule{ + { + BackendRefs: []gwv1beta1.BackendRef{ + { + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(25000)), + }, + Weight: common.PointerTo(int32(-50)), + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} From 7e076bb6f9d95e6214b0a2ef66caeb8450740d84 Mon Sep 17 00:00:00 2001 From: skpratt Date: Fri, 9 Jun 2023 23:24:35 -0500 Subject: [PATCH 015/120] Add CRT docker changes for release workflow (#2333) --- .github/workflows/build.yml | 74 +++++++++++++++++++++++++++++++++++-- control-plane/Dockerfile | 5 +++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8eef629401..e46e16c9a3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -271,6 +271,7 @@ jobs: unzip -j *.zip - name: Docker Build (Action) uses: hashicorp/actions-docker-build@v1 + if: ${{ !matrix.fips }} with: smoke_test: | TEST_VERSION="$(docker run "${IMAGE_NAME}" consul-k8s-control-plane version | awk '{print $2}')" @@ -291,6 +292,29 @@ jobs: hashicorppreview/${{ env.repo }}-control-plane:${{ env.version }} docker.io/hashicorppreview/${{ env.repo }}-control-plane:${{ env.version }}-${{ github.sha }} + - name: Docker FIPS Build (Action) + uses: hashicorp/actions-docker-build@v1 + if: ${{ matrix.fips }} + with: + smoke_test: | + TEST_VERSION="$(docker run "${IMAGE_NAME}" consul-k8s-control-plane version | awk '{print $2}')" + if [ "${TEST_VERSION}" != "v${version}" ]; then + echo "Test FAILED" + exit 1 + fi + echo "Test PASSED" + version: ${{ env.version }} + target: release-default-fips # duplicate target to distinguish FIPS builds in CRT machinery + arch: ${{ matrix.goarch }} + pkg_name: consul-k8s-control-plane_${{ env.version }} + bin_name: consul-k8s-control-plane + workdir: control-plane + tags: | + docker.io/hashicorp/${{ env.repo }}-control-plane-fips:${{ env.version }} + dev_tags: | + hashicorppreview/${{ env.repo }}-control-plane-fips:${{ env.version }} + docker.io/hashicorppreview/${{ env.repo }}-control-plane-fips:${{ env.version }}-${{ github.sha }} + build-docker-ubi-redhat-registry: name: Docker ${{ matrix.arch }} ${{ matrix.fips }} UBI build for RedHat Registry needs: [get-product-version, build] @@ -318,7 +342,9 @@ jobs: - name: Copy LICENSE run: cp LICENSE ./control-plane - - uses: hashicorp/actions-docker-build@v1 + - name: Docker Build (Action) + if: ${{ !matrix.fips }} + uses: hashicorp/actions-docker-build@v1 with: smoke_test: | TEST_VERSION="$(docker run "${IMAGE_NAME}" consul-k8s-control-plane version | awk '{print $2}')" @@ -334,6 +360,24 @@ jobs: bin_name: consul-k8s-control-plane workdir: control-plane redhat_tag: quay.io/redhat-isv-containers/611ca2f89a9b407267837100:${{env.version}}-ubi + - name: Docker FIPS Build (Action) + if: ${{ matrix.fips }} + uses: hashicorp/actions-docker-build@v1 + with: + smoke_test: | + TEST_VERSION="$(docker run "${IMAGE_NAME}" consul-k8s-control-plane version | awk '{print $2}')" + if [ "${TEST_VERSION}" != "v${version}" ]; then + echo "Test FAILED" + exit 1 + fi + echo "Test PASSED" + version: ${{ env.version }} + target: ubi-fips # duplicate target to distinguish FIPS builds in CRT machinery + arch: ${{ matrix.arch }} + pkg_name: consul-k8s-control-plane_${{ env.version }} + bin_name: consul-k8s-control-plane + workdir: control-plane + redhat_tag: quay.io/redhat-isv-containers/6483ed53b430df51b731406c:${{env.version}}-ubi # this is different than the non-FIPS one build-docker-ubi-dockerhub: name: Docker ${{ matrix.arch }} ${{ matrix.fips }} UBI build for DockerHub @@ -361,7 +405,9 @@ jobs: - name: Copy LICENSE run: cp LICENSE ./control-plane - - uses: hashicorp/actions-docker-build@v1 + - name: Docker Build (Action) + uses: hashicorp/actions-docker-build@v1 + if: ${{ !matrix.fips }} with: smoke_test: | TEST_VERSION="$(docker run "${IMAGE_NAME}" consul-k8s-control-plane version | awk '{print $2}')" @@ -380,4 +426,26 @@ jobs: docker.io/hashicorp/${{ env.repo }}-control-plane:${{ env.version }}-ubi dev_tags: | hashicorppreview/${{ env.repo }}-control-plane:${{ env.version }}-ubi - docker.io/hashicorppreview/${{ env.repo }}-control-plane:${{ env.version }}-ubi-${{ github.sha }} + docker.io/hashicorppreview/${{ env.repo }}-control-plane:${{ env.version }}-ubi-${{ github.sha }} + - name: Docker FIPS Build (Action) + uses: hashicorp/actions-docker-build@v1 + if: ${{ matrix.fips }} + with: + smoke_test: | + TEST_VERSION="$(docker run "${IMAGE_NAME}" consul-k8s-control-plane version | awk '{print $2}')" + if [ "${TEST_VERSION}" != "v${version}" ]; then + echo "Test FAILED" + exit 1 + fi + echo "Test PASSED" + version: ${{ env.version }} + target: ubi-fips # duplicate target to distinguish FIPS builds in CRT machinery + arch: ${{ matrix.arch }} + pkg_name: consul-k8s-control-plane_${{ env.version }} + bin_name: consul-k8s-control-plane + workdir: control-plane + tags: | + docker.io/hashicorp/${{ env.repo }}-control-plane-fips:${{ env.version }}-ubi + dev_tags: | + hashicorppreview/${{ env.repo }}-control-plane-fips:${{ env.version }}-ubi + docker.io/hashicorppreview/${{ env.repo }}-control-plane-fips:${{ env.version }}-ubi-${{ github.sha }} diff --git a/control-plane/Dockerfile b/control-plane/Dockerfile index 5b3d73e625..f401ac8262 100644 --- a/control-plane/Dockerfile +++ b/control-plane/Dockerfile @@ -113,6 +113,9 @@ COPY dist/cni/${TARGETOS}/${TARGETARCH}/${CNI_BIN_NAME} /bin/ USER 100 CMD /bin/${BIN_NAME} +# Duplicate target for FIPS builds +FROM release-default AS release-default-fips + # ----------------------------------- # Dockerfile target for consul-k8s with UBI as its base image. Used for running on # OpenShift. @@ -175,6 +178,8 @@ COPY dist/cni/${TARGETOS}/${TARGETARCH}/${CNI_BIN_NAME} /bin/ USER 100 CMD /bin/${BIN_NAME} +# Duplicate target for FIPS builds +FROM ubi AS ubi-fips # =================================== # # Set default target to 'dev'. From 497621505160edd41ef209522f8924c90166c44d Mon Sep 17 00:00:00 2001 From: skpratt Date: Sun, 11 Jun 2023 16:45:14 -0500 Subject: [PATCH 016/120] Update var check with appropriate quotes (#2330) --- control-plane/build-support/functions/20-build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/control-plane/build-support/functions/20-build.sh b/control-plane/build-support/functions/20-build.sh index e9540956c9..dac626b88f 100644 --- a/control-plane/build-support/functions/20-build.sh +++ b/control-plane/build-support/functions/20-build.sh @@ -188,7 +188,7 @@ function build_consul_local { # build with go install. # The GOXPARALLEL environment variable is used if set - if [ $GOTAGS == "fips" ]; then + if [ "${GOTAGS:-}" == "fips" ]; then CGO_ENABLED=1 else CGO_ENABLED=0 From 60b214e19707f4739b628ed0b979a24eac903b3a Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Mon, 12 Jun 2023 12:50:16 -0400 Subject: [PATCH 017/120] Revert "Ensure Reconciliation Stops (#2305)" (#2341) This reverts commit 7f6e1cb5c4c2d8797944c1a3e0dcd12943f75138. --- .../gateway_controller_integration_test.go | 1320 ----------------- 1 file changed, 1320 deletions(-) delete mode 100644 control-plane/api-gateway/controllers/gateway_controller_integration_test.go diff --git a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go deleted file mode 100644 index 5dd5357d77..0000000000 --- a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go +++ /dev/null @@ -1,1320 +0,0 @@ -package controllers - -import ( - "context" - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - "fmt" - "math/big" - "sync" - "testing" - "time" - - mapset "github.com/deckarep/golang-set" - logrtest "github.com/go-logr/logr/testr" - "github.com/stretchr/testify/require" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/gateway-api/apis/v1alpha2" - gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" - gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" - - "github.com/hashicorp/consul-k8s/control-plane/api-gateway/cache" - "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" - "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" - "github.com/hashicorp/consul-k8s/control-plane/helper/test" - "github.com/hashicorp/consul/api" -) - -func TestControllerDoesNotInfinitelyReconcile(t *testing.T) { - s := runtime.NewScheme() - require.NoError(t, clientgoscheme.AddToScheme(s)) - require.NoError(t, gwv1alpha2.Install(s)) - require.NoError(t, gwv1beta1.Install(s)) - require.NoError(t, v1alpha1.AddToScheme(s)) - - testCases := map[string]struct { - namespace string - certFn func(*testing.T, context.Context, client.WithWatch, string) *corev1.Secret - gwFn func(*testing.T, context.Context, client.WithWatch, string) *gwv1beta1.Gateway - httpRouteFn func(*testing.T, context.Context, client.WithWatch, *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute - tcpRouteFn func(*testing.T, context.Context, client.WithWatch, *gwv1beta1.Gateway) *v1alpha2.TCPRoute - }{ - "all fields set": { - namespace: "consul", - certFn: createCert, - gwFn: createAllFieldsSetAPIGW, - httpRouteFn: createAllFieldsSetHTTPRoute, - tcpRouteFn: createAllFieldsSetTCPRoute, - }, - "minimal fields set": { - namespace: "", - certFn: createCert, - gwFn: minimalFieldsSetAPIGW, - httpRouteFn: minimalFieldsSetHTTPRoute, - tcpRouteFn: minimalFieldsSetTCPRoute, - }, - "funky casing to test normalization doesnt cause infinite reconciliation": { - namespace: "", - certFn: createCert, - gwFn: createFunkyCasingFieldsAPIGW, - httpRouteFn: createFunkyCasingFieldsHTTPRoute, - tcpRouteFn: createFunkyCasingFieldsTCPRoute, - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - k8sClient := registerFieldIndexersForTest(fake.NewClientBuilder().WithScheme(s)).Build() - consulTestServerClient := test.TestServerWithMockConnMgrWatcher(t, nil) - ctx, cancel := context.WithCancel(context.Background()) - - t.Cleanup(func() { - cancel() - }) - logger := logrtest.New(t) - - cacheCfg := cache.Config{ - ConsulClientConfig: consulTestServerClient.Cfg, - ConsulServerConnMgr: consulTestServerClient.Watcher, - Logger: logger, - } - resourceCache := cache.New(cacheCfg) - - gwCache := cache.NewGatewayCache(ctx, cacheCfg) - - gwCtrl := GatewayController{ - HelmConfig: common.HelmConfig{}, - Log: logger, - Translator: common.ResourceTranslator{}, - cache: resourceCache, - gatewayCache: gwCache, - Client: k8sClient, - allowK8sNamespacesSet: mapset.NewSet(), - denyK8sNamespacesSet: mapset.NewSet(), - } - - go func() { - resourceCache.Run(ctx) - }() - - resourceCache.WaitSynced(ctx) - - gwSub := resourceCache.Subscribe(ctx, api.APIGateway, gwCtrl.transformConsulGateway) - httpRouteSub := resourceCache.Subscribe(ctx, api.HTTPRoute, gwCtrl.transformConsulHTTPRoute(ctx)) - tcpRouteSub := resourceCache.Subscribe(ctx, api.TCPRoute, gwCtrl.transformConsulTCPRoute(ctx)) - inlineCertSub := resourceCache.Subscribe(ctx, api.InlineCertificate, gwCtrl.transformConsulInlineCertificate(ctx)) - - cert := tc.certFn(t, ctx, k8sClient, tc.namespace) - k8sGWObj := tc.gwFn(t, ctx, k8sClient, tc.namespace) - - // reconcile so we add the finalizer - _, err := gwCtrl.Reconcile(ctx, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: k8sGWObj.Namespace, - Name: k8sGWObj.Name, - }, - }) - require.NoError(t, err) - - // reconcile again so that we get the creation with the finalizer - _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: k8sGWObj.Namespace, - Name: k8sGWObj.Name, - }, - }) - require.NoError(t, err) - - httpRouteObj := tc.httpRouteFn(t, ctx, k8sClient, k8sGWObj) - tcpRouteObj := tc.tcpRouteFn(t, ctx, k8sClient, k8sGWObj) - - // reconcile again so that we get the route bound to the gateway - _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: k8sGWObj.Namespace, - Name: k8sGWObj.Name, - }, - }) - require.NoError(t, err) - - // reconcile again so that we get the route bound to the gateway - _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: k8sGWObj.Namespace, - Name: k8sGWObj.Name, - }, - }) - require.NoError(t, err) - - wg := &sync.WaitGroup{} - // we never get the event from the cert because when it's created there are no gateways that reference it - wg.Add(3) - go func(w *sync.WaitGroup) { - gwDone := false - httpRouteDone := false - tcpRouteDone := false - for { - // get the creation events from the upsert and then continually read from channel so we dont block other subs - select { - case <-ctx.Done(): - return - case <-gwSub.Events(): - if !gwDone { - gwDone = true - wg.Done() - } - case <-httpRouteSub.Events(): - if !httpRouteDone { - httpRouteDone = true - wg.Done() - } - case <-tcpRouteSub.Events(): - if !tcpRouteDone { - tcpRouteDone = true - wg.Done() - } - case <-inlineCertSub.Events(): - } - } - }(wg) - - wg.Wait() - - gwNamespaceName := types.NamespacedName{ - Name: k8sGWObj.Name, - Namespace: k8sGWObj.Namespace, - } - - httpRouteNamespaceName := types.NamespacedName{ - Name: httpRouteObj.Name, - Namespace: httpRouteObj.Namespace, - } - - tcpRouteNamespaceName := types.NamespacedName{ - Name: tcpRouteObj.Name, - Namespace: tcpRouteObj.Namespace, - } - - certNamespaceName := types.NamespacedName{ - Name: cert.Name, - Namespace: cert.Namespace, - } - - gwRef := gwCtrl.Translator.ConfigEntryReference(api.APIGateway, gwNamespaceName) - httpRouteRef := gwCtrl.Translator.ConfigEntryReference(api.HTTPRoute, httpRouteNamespaceName) - tcpRouteRef := gwCtrl.Translator.ConfigEntryReference(api.TCPRoute, tcpRouteNamespaceName) - certRef := gwCtrl.Translator.ConfigEntryReference(api.InlineCertificate, certNamespaceName) - - curGWModifyIndex := resourceCache.Get(gwRef).GetModifyIndex() - curHTTPRouteModifyIndex := resourceCache.Get(httpRouteRef).GetModifyIndex() - curTCPRouteModifyIndex := resourceCache.Get(tcpRouteRef).GetModifyIndex() - curCertModifyIndex := resourceCache.Get(certRef).GetModifyIndex() - - err = k8sClient.Get(ctx, gwNamespaceName, k8sGWObj) - require.NoError(t, err) - curGWResourceVersion := k8sGWObj.ResourceVersion - - err = k8sClient.Get(ctx, httpRouteNamespaceName, httpRouteObj) - require.NoError(t, err) - curHTTPRouteResourceVersion := httpRouteObj.ResourceVersion - - err = k8sClient.Get(ctx, tcpRouteNamespaceName, tcpRouteObj) - require.NoError(t, err) - curTCPRouteResourceVersion := tcpRouteObj.ResourceVersion - - err = k8sClient.Get(ctx, certNamespaceName, cert) - require.NoError(t, err) - curCertResourceVersion := cert.ResourceVersion - - go func() { - // reconcile multiple times with no changes to be sure - for i := 0; i < 5; i++ { - _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: k8sGWObj.Namespace, - }, - }) - require.NoError(t, err) - } - }() - - require.Never(t, func() bool { - err = k8sClient.Get(ctx, gwNamespaceName, k8sGWObj) - require.NoError(t, err) - newGWResourceVersion := k8sGWObj.ResourceVersion - - err = k8sClient.Get(ctx, httpRouteNamespaceName, httpRouteObj) - require.NoError(t, err) - newHTTPRouteResourceVersion := httpRouteObj.ResourceVersion - - err = k8sClient.Get(ctx, tcpRouteNamespaceName, tcpRouteObj) - require.NoError(t, err) - newTCPRouteResourceVersion := tcpRouteObj.ResourceVersion - - err = k8sClient.Get(ctx, certNamespaceName, cert) - require.NoError(t, err) - newCertResourceVersion := cert.ResourceVersion - - return curGWModifyIndex == resourceCache.Get(gwRef).GetModifyIndex() && - curGWResourceVersion == newGWResourceVersion && - curHTTPRouteModifyIndex == resourceCache.Get(httpRouteRef).GetModifyIndex() && - curHTTPRouteResourceVersion == newHTTPRouteResourceVersion && - curTCPRouteModifyIndex == resourceCache.Get(tcpRouteRef).GetModifyIndex() && - curTCPRouteResourceVersion == newTCPRouteResourceVersion && - curCertModifyIndex == resourceCache.Get(certRef).GetModifyIndex() && - curCertResourceVersion == newCertResourceVersion - }, time.Duration(2*time.Second), time.Duration(500*time.Millisecond), fmt.Sprintf("curGWModifyIndex: %d, newIndx: %d", curGWModifyIndex, resourceCache.Get(gwRef).GetModifyIndex()), - ) - }) - } -} - -func createAllFieldsSetAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { - // listener one configuration - listenerOneName := "listener-one" - listenerOneHostname := "*.consul.io" - listenerOnePort := 3366 - listenerOneProtocol := "https" - - // listener two configuration - listenerTwoName := "listener-two" - listenerTwoHostname := "*.consul.io" - listenerTwoPort := 5432 - listenerTwoProtocol := "http" - - // listener three configuration - listenerThreeName := "listener-three" - listenerThreePort := 8081 - listenerThreeProtocol := "tcp" - - // listener four configuration - listenerFourName := "listener-four" - listenerFourHostname := "*.consul.io" - listenerFourPort := 5433 - listenerFourProtocol := "http" - - // Write gw to k8s - gwClassCfg := &v1alpha1.GatewayClassConfig{ - TypeMeta: metav1.TypeMeta{ - Kind: "GatewayClassConfig", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gateway-class-config", - }, - Spec: v1alpha1.GatewayClassConfigSpec{}, - } - gwClass := &gwv1beta1.GatewayClass{ - TypeMeta: metav1.TypeMeta{ - Kind: "GatewayClass", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gatewayclass", - }, - Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: "hashicorp.com/consul-api-gateway-controller", - ParametersRef: &gwv1beta1.ParametersReference{ - Group: "consul.hashicorp.com", - Kind: "GatewayClassConfig", - Name: "gateway-class-config", - }, - Description: new(string), - }, - } - gw := &gwv1beta1.Gateway{ - TypeMeta: metav1.TypeMeta{ - Kind: "Gateway", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gw", - Namespace: namespace, - Annotations: make(map[string]string), - }, - Spec: gwv1beta1.GatewaySpec{ - GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), - Listeners: []gwv1beta1.Listener{ - { - Name: gwv1beta1.SectionName(listenerOneName), - Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), - Port: gwv1beta1.PortNumber(listenerOnePort), - Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), - TLS: &gwv1beta1.GatewayTLSConfig{ - CertificateRefs: []gwv1beta1.SecretObjectReference{ - { - Kind: common.PointerTo(gwv1beta1.Kind("Secret")), - Name: gwv1beta1.ObjectName("one-cert"), - Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), - }, - }, - }, - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("All")), - }, - }, - }, - { - Name: gwv1beta1.SectionName(listenerTwoName), - Hostname: common.PointerTo(gwv1beta1.Hostname(listenerTwoHostname)), - Port: gwv1beta1.PortNumber(listenerTwoPort), - Protocol: gwv1beta1.ProtocolType(listenerTwoProtocol), - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("Same")), - }, - }, - }, - { - Name: gwv1beta1.SectionName(listenerThreeName), - Port: gwv1beta1.PortNumber(listenerThreePort), - Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("All")), - }, - }, - }, - { - Name: gwv1beta1.SectionName(listenerFourName), - Hostname: common.PointerTo(gwv1beta1.Hostname(listenerFourHostname)), - Port: gwv1beta1.PortNumber(listenerFourPort), - Protocol: gwv1beta1.ProtocolType(listenerFourProtocol), - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("Selector")), - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.NamespaceNameLabel: "consul", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{}, - }, - }, - }, - }, - }, - }, - } - - err := k8sClient.Create(ctx, gwClassCfg) - require.NoError(t, err) - - err = k8sClient.Create(ctx, gwClass) - require.NoError(t, err) - - err = k8sClient.Create(ctx, gw) - require.NoError(t, err) - - return gw -} - -func createAllFieldsSetHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { - svcDefault := &v1alpha1.ServiceDefaults{ - TypeMeta: metav1.TypeMeta{ - Kind: "ServiceDefaults", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - }, - Spec: v1alpha1.ServiceDefaultsSpec{ - Protocol: "http", - }, - } - - svc := &corev1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - Labels: map[string]string{"app": "Service"}, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "high", - Protocol: "TCP", - Port: 8080, - }, - }, - Selector: map[string]string{"app": "Service"}, - }, - } - - serviceAccount := &corev1.ServiceAccount{ - TypeMeta: metav1.TypeMeta{ - Kind: "ServiceAccount", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - }, - } - - deployment := &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - Labels: map[string]string{"app": "Service"}, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: common.PointerTo(int32(1)), - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": "Service"}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{}, - Spec: corev1.PodSpec{}, - }, - }, - } - - err := k8sClient.Create(ctx, svcDefault) - require.NoError(t, err) - - err = k8sClient.Create(ctx, svc) - require.NoError(t, err) - - err = k8sClient.Create(ctx, serviceAccount) - require.NoError(t, err) - - err = k8sClient.Create(ctx, deployment) - require.NoError(t, err) - - route := &gwv1beta1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - Kind: "HTTPRoute", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "http-route", - }, - Spec: gwv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gwv1beta1.CommonRouteSpec{ - ParentRefs: []gwv1beta1.ParentReference{ - { - Kind: (*gwv1beta1.Kind)(&gw.Kind), - Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), - Name: gwv1beta1.ObjectName(gw.Name), - SectionName: &gw.Spec.Listeners[0].Name, - Port: &gw.Spec.Listeners[0].Port, - }, - }, - }, - Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, - Rules: []gwv1beta1.HTTPRouteRule{ - { - Matches: []gwv1beta1.HTTPRouteMatch{ - { - Path: &gwv1beta1.HTTPPathMatch{ - Type: common.PointerTo(gwv1beta1.PathMatchType("PathPrefix")), - Value: common.PointerTo("/v1"), - }, - Headers: []gwv1beta1.HTTPHeaderMatch{ - { - Type: common.PointerTo(gwv1beta1.HeaderMatchExact), - Name: "version", - Value: "version", - }, - }, - QueryParams: []gwv1beta1.HTTPQueryParamMatch{ - { - Type: common.PointerTo(gwv1beta1.QueryParamMatchExact), - Name: "search", - Value: "q", - }, - }, - Method: common.PointerTo(gwv1beta1.HTTPMethod("GET")), - }, - }, - Filters: []gwv1beta1.HTTPRouteFilter{ - { - Type: gwv1beta1.HTTPRouteFilterRequestHeaderModifier, - RequestHeaderModifier: &gwv1beta1.HTTPHeaderFilter{ - Set: []gwv1beta1.HTTPHeader{ - { - Name: "foo", - Value: "bax", - }, - }, - Add: []gwv1beta1.HTTPHeader{ - { - Name: "arc", - Value: "reactor", - }, - }, - Remove: []string{"remove"}, - }, - }, - { - Type: gwv1beta1.HTTPRouteFilterURLRewrite, - URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ - Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), - Path: &gwv1beta1.HTTPPathModifier{ - Type: gwv1beta1.FullPathHTTPPathModifier, - ReplaceFullPath: common.PointerTo("/foobar"), - }, - }, - }, - - { - Type: gwv1beta1.HTTPRouteFilterURLRewrite, - URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ - Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), - Path: &gwv1beta1.HTTPPathModifier{ - Type: gwv1beta1.PrefixMatchHTTPPathModifier, - ReplacePrefixMatch: common.PointerTo("/foo"), - }, - }, - }, - }, - BackendRefs: []gwv1beta1.HTTPBackendRef{ - { - BackendRef: gwv1beta1.BackendRef{ - BackendObjectReference: gwv1beta1.BackendObjectReference{ - Name: "Service", - Port: common.PointerTo(gwv1beta1.PortNumber(8080)), - }, - Weight: common.PointerTo(int32(50)), - }, - }, - }, - }, - }, - }, - } - - err = k8sClient.Create(ctx, route) - require.NoError(t, err) - - return route -} - -func createAllFieldsSetTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { - route := &v1alpha2.TCPRoute{ - TypeMeta: metav1.TypeMeta{ - Kind: "TCPRoute", - APIVersion: "gateway.networking.k8s.io/v1alpha2", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "tcp-route", - }, - Spec: gwv1alpha2.TCPRouteSpec{ - CommonRouteSpec: gwv1beta1.CommonRouteSpec{ - ParentRefs: []gwv1beta1.ParentReference{ - { - Kind: (*gwv1beta1.Kind)(&gw.Kind), - Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), - Name: gwv1beta1.ObjectName(gw.Name), - SectionName: &gw.Spec.Listeners[2].Name, - Port: &gw.Spec.Listeners[2].Port, - }, - }, - }, - Rules: []gwv1alpha2.TCPRouteRule{ - { - BackendRefs: []gwv1beta1.BackendRef{ - { - BackendObjectReference: gwv1beta1.BackendObjectReference{ - Name: "Service", - Port: common.PointerTo(gwv1beta1.PortNumber(25000)), - }, - Weight: common.PointerTo(int32(50)), - }, - }, - }, - }, - }, - } - - err := k8sClient.Create(ctx, route) - require.NoError(t, err) - - return route -} - -func createCert(t *testing.T, ctx context.Context, k8sClient client.WithWatch, certNS string) *corev1.Secret { - // listener one tls config - certName := "one-cert" - - privateKey, err := rsa.GenerateKey(rand.Reader, 1024) - require.NoError(t, err) - - usage := x509.KeyUsageCertSign - expiration := time.Now().AddDate(10, 0, 0) - - cert := &x509.Certificate{ - SerialNumber: big.NewInt(1), - Subject: pkix.Name{ - CommonName: "consul.test", - }, - IsCA: true, - NotBefore: time.Now().Add(-10 * time.Minute), - NotAfter: expiration, - SubjectKeyId: []byte{1, 2, 3, 4, 6}, - ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, - KeyUsage: usage, - BasicConstraintsValid: true, - } - caCert := cert - caPrivateKey := privateKey - - data, err := x509.CreateCertificate(rand.Reader, cert, caCert, &privateKey.PublicKey, caPrivateKey) - require.NoError(t, err) - - certBytes := pem.EncodeToMemory(&pem.Block{ - Type: "CERTIFICATE", - Bytes: data, - }) - - privateKeyBytes := pem.EncodeToMemory(&pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: x509.MarshalPKCS1PrivateKey(privateKey), - }) - - secret := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Namespace: certNS, - Name: certName, - }, - Data: map[string][]byte{ - corev1.TLSCertKey: certBytes, - corev1.TLSPrivateKeyKey: privateKeyBytes, - }, - } - - err = k8sClient.Create(ctx, secret) - require.NoError(t, err) - - return secret -} - -func minimalFieldsSetAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { - // listener one configuration - listenerOneName := "listener-one" - listenerOneHostname := "*.consul.io" - listenerOnePort := 3366 - listenerOneProtocol := "https" - - // listener three configuration - listenerThreeName := "listener-three" - listenerThreePort := 8081 - listenerThreeProtocol := "tcp" - - // Write gw to k8s - gwClassCfg := &v1alpha1.GatewayClassConfig{ - TypeMeta: metav1.TypeMeta{ - Kind: "GatewayClassConfig", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gateway-class-config", - }, - Spec: v1alpha1.GatewayClassConfigSpec{}, - } - gwClass := &gwv1beta1.GatewayClass{ - TypeMeta: metav1.TypeMeta{ - Kind: "GatewayClass", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gatewayclass", - }, - Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: "hashicorp.com/consul-api-gateway-controller", - ParametersRef: &gwv1beta1.ParametersReference{ - Group: "consul.hashicorp.com", - Kind: "GatewayClassConfig", - Name: "gateway-class-config", - }, - Description: new(string), - }, - } - gw := &gwv1beta1.Gateway{ - TypeMeta: metav1.TypeMeta{ - Kind: "Gateway", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gw", - Annotations: make(map[string]string), - }, - Spec: gwv1beta1.GatewaySpec{ - GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), - Listeners: []gwv1beta1.Listener{ - { - Name: gwv1beta1.SectionName(listenerOneName), - Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), - Port: gwv1beta1.PortNumber(listenerOnePort), - Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), - TLS: &gwv1beta1.GatewayTLSConfig{ - CertificateRefs: []gwv1beta1.SecretObjectReference{ - { - Kind: common.PointerTo(gwv1beta1.Kind("Secret")), - Name: gwv1beta1.ObjectName("one-cert"), - Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), - }, - }, - }, - }, - { - Name: gwv1beta1.SectionName(listenerThreeName), - Port: gwv1beta1.PortNumber(listenerThreePort), - Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("All")), - }, - }, - }, - }, - }, - } - - err := k8sClient.Create(ctx, gwClassCfg) - require.NoError(t, err) - - err = k8sClient.Create(ctx, gwClass) - require.NoError(t, err) - - err = k8sClient.Create(ctx, gw) - require.NoError(t, err) - - return gw -} - -func minimalFieldsSetHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { - svcDefault := &v1alpha1.ServiceDefaults{ - TypeMeta: metav1.TypeMeta{ - Kind: "ServiceDefaults", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - }, - Spec: v1alpha1.ServiceDefaultsSpec{ - Protocol: "http", - }, - } - - svc := &corev1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - Labels: map[string]string{"app": "Service"}, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "high", - Protocol: "TCP", - Port: 8080, - }, - }, - Selector: map[string]string{"app": "Service"}, - }, - } - - serviceAccount := &corev1.ServiceAccount{ - TypeMeta: metav1.TypeMeta{ - Kind: "ServiceAccount", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - }, - } - - deployment := &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - Labels: map[string]string{"app": "Service"}, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: common.PointerTo(int32(1)), - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": "Service"}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{}, - Spec: corev1.PodSpec{}, - }, - }, - } - - err := k8sClient.Create(ctx, svcDefault) - require.NoError(t, err) - - err = k8sClient.Create(ctx, svc) - require.NoError(t, err) - - err = k8sClient.Create(ctx, serviceAccount) - require.NoError(t, err) - - err = k8sClient.Create(ctx, deployment) - require.NoError(t, err) - - route := &gwv1beta1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - Kind: "HTTPRoute", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "http-route", - }, - Spec: gwv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gwv1beta1.CommonRouteSpec{ - ParentRefs: []gwv1beta1.ParentReference{ - { - Kind: (*gwv1beta1.Kind)(&gw.Kind), - Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), - Name: gwv1beta1.ObjectName(gw.Name), - SectionName: &gw.Spec.Listeners[0].Name, - Port: &gw.Spec.Listeners[0].Port, - }, - }, - }, - Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, - Rules: []gwv1beta1.HTTPRouteRule{ - { - BackendRefs: []gwv1beta1.HTTPBackendRef{ - { - BackendRef: gwv1beta1.BackendRef{ - BackendObjectReference: gwv1beta1.BackendObjectReference{ - Name: "Service", - Port: common.PointerTo(gwv1beta1.PortNumber(8080)), - }, - }, - }, - }, - }, - }, - }, - } - - err = k8sClient.Create(ctx, route) - require.NoError(t, err) - - return route -} - -func minimalFieldsSetTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { - route := &v1alpha2.TCPRoute{ - TypeMeta: metav1.TypeMeta{ - Kind: "TCPRoute", - APIVersion: "gateway.networking.k8s.io/v1alpha2", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "tcp-route", - }, - Spec: gwv1alpha2.TCPRouteSpec{ - CommonRouteSpec: gwv1beta1.CommonRouteSpec{ - ParentRefs: []gwv1beta1.ParentReference{ - { - Kind: (*gwv1beta1.Kind)(&gw.Kind), - Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), - Name: gwv1beta1.ObjectName(gw.Name), - SectionName: &gw.Spec.Listeners[1].Name, - Port: &gw.Spec.Listeners[1].Port, - }, - }, - }, - Rules: []gwv1alpha2.TCPRouteRule{ - { - BackendRefs: []gwv1beta1.BackendRef{ - { - BackendObjectReference: gwv1beta1.BackendObjectReference{ - Name: "Service", - Port: common.PointerTo(gwv1beta1.PortNumber(25000)), - }, - }, - }, - }, - }, - }, - } - - err := k8sClient.Create(ctx, route) - require.NoError(t, err) - - return route -} - -func createFunkyCasingFieldsAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { - // listener one configuration - listenerOneName := "listener-one" - listenerOneHostname := "*.consul.io" - listenerOnePort := 3366 - listenerOneProtocol := "hTtPs" - - // listener two configuration - listenerTwoName := "listener-two" - listenerTwoHostname := "*.consul.io" - listenerTwoPort := 5432 - listenerTwoProtocol := "HTTP" - - // listener three configuration - listenerThreeName := "listener-three" - listenerThreePort := 8081 - listenerThreeProtocol := "tCp" - - // listener four configuration - listenerFourName := "listener-four" - listenerFourHostname := "*.consul.io" - listenerFourPort := 5433 - listenerFourProtocol := "hTTp" - - // Write gw to k8s - gwClassCfg := &v1alpha1.GatewayClassConfig{ - TypeMeta: metav1.TypeMeta{ - Kind: "GatewayClassConfig", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gateway-class-config", - }, - Spec: v1alpha1.GatewayClassConfigSpec{}, - } - gwClass := &gwv1beta1.GatewayClass{ - TypeMeta: metav1.TypeMeta{ - Kind: "GatewayClass", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gatewayclass", - }, - Spec: gwv1beta1.GatewayClassSpec{ - ControllerName: "hashicorp.com/consul-api-gateway-controller", - ParametersRef: &gwv1beta1.ParametersReference{ - Group: "consul.hashicorp.com", - Kind: "GatewayClassConfig", - Name: "gateway-class-config", - }, - Description: new(string), - }, - } - gw := &gwv1beta1.Gateway{ - TypeMeta: metav1.TypeMeta{ - Kind: "Gateway", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "gw", - Namespace: namespace, - Annotations: make(map[string]string), - }, - Spec: gwv1beta1.GatewaySpec{ - GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), - Listeners: []gwv1beta1.Listener{ - { - Name: gwv1beta1.SectionName(listenerOneName), - Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), - Port: gwv1beta1.PortNumber(listenerOnePort), - Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), - TLS: &gwv1beta1.GatewayTLSConfig{ - CertificateRefs: []gwv1beta1.SecretObjectReference{ - { - Kind: common.PointerTo(gwv1beta1.Kind("Secret")), - Name: gwv1beta1.ObjectName("one-cert"), - Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), - }, - }, - }, - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("All")), - }, - }, - }, - { - Name: gwv1beta1.SectionName(listenerTwoName), - Hostname: common.PointerTo(gwv1beta1.Hostname(listenerTwoHostname)), - Port: gwv1beta1.PortNumber(listenerTwoPort), - Protocol: gwv1beta1.ProtocolType(listenerTwoProtocol), - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("Same")), - }, - }, - }, - { - Name: gwv1beta1.SectionName(listenerThreeName), - Port: gwv1beta1.PortNumber(listenerThreePort), - Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("All")), - }, - }, - }, - { - Name: gwv1beta1.SectionName(listenerFourName), - Hostname: common.PointerTo(gwv1beta1.Hostname(listenerFourHostname)), - Port: gwv1beta1.PortNumber(listenerFourPort), - Protocol: gwv1beta1.ProtocolType(listenerFourProtocol), - AllowedRoutes: &gwv1beta1.AllowedRoutes{ - Namespaces: &gwv1beta1.RouteNamespaces{ - From: common.PointerTo(gwv1beta1.FromNamespaces("Selector")), - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - common.NamespaceNameLabel: "consul", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{}, - }, - }, - }, - }, - }, - }, - } - - err := k8sClient.Create(ctx, gwClassCfg) - require.NoError(t, err) - - err = k8sClient.Create(ctx, gwClass) - require.NoError(t, err) - - err = k8sClient.Create(ctx, gw) - require.NoError(t, err) - - return gw -} - -func createFunkyCasingFieldsHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { - svcDefault := &v1alpha1.ServiceDefaults{ - TypeMeta: metav1.TypeMeta{ - Kind: "ServiceDefaults", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - }, - Spec: v1alpha1.ServiceDefaultsSpec{ - Protocol: "hTtp", - }, - } - - svc := &corev1.Service{ - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - Labels: map[string]string{"app": "Service"}, - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Name: "high", - Protocol: "TCP", - Port: 8080, - }, - }, - Selector: map[string]string{"app": "Service"}, - }, - } - - serviceAccount := &corev1.ServiceAccount{ - TypeMeta: metav1.TypeMeta{ - Kind: "ServiceAccount", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - }, - } - - deployment := &appsv1.Deployment{ - TypeMeta: metav1.TypeMeta{ - Kind: "Deployment", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "Service", - Labels: map[string]string{"app": "Service"}, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: common.PointerTo(int32(1)), - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": "Service"}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{}, - Spec: corev1.PodSpec{}, - }, - }, - } - - err := k8sClient.Create(ctx, svcDefault) - require.NoError(t, err) - - err = k8sClient.Create(ctx, svc) - require.NoError(t, err) - - err = k8sClient.Create(ctx, serviceAccount) - require.NoError(t, err) - - err = k8sClient.Create(ctx, deployment) - require.NoError(t, err) - - route := &gwv1beta1.HTTPRoute{ - TypeMeta: metav1.TypeMeta{ - Kind: "HTTPRoute", - APIVersion: "gateway.networking.k8s.io/v1beta1", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "http-route", - }, - Spec: gwv1beta1.HTTPRouteSpec{ - CommonRouteSpec: gwv1beta1.CommonRouteSpec{ - ParentRefs: []gwv1beta1.ParentReference{ - { - Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), - Name: gwv1beta1.ObjectName(gw.Name), - SectionName: &gw.Spec.Listeners[0].Name, - Port: &gw.Spec.Listeners[0].Port, - }, - }, - }, - Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, - Rules: []gwv1beta1.HTTPRouteRule{ - { - Matches: []gwv1beta1.HTTPRouteMatch{ - { - Path: &gwv1beta1.HTTPPathMatch{ - Type: common.PointerTo(gwv1beta1.PathMatchPathPrefix), - }, - Headers: []gwv1beta1.HTTPHeaderMatch{ - { - Type: common.PointerTo(gwv1beta1.HeaderMatchExact), - Name: "version", - Value: "version", - }, - }, - QueryParams: []gwv1beta1.HTTPQueryParamMatch{ - { - Type: common.PointerTo(gwv1beta1.QueryParamMatchExact), - Name: "search", - Value: "q", - }, - }, - Method: common.PointerTo(gwv1beta1.HTTPMethod("geT")), - }, - }, - Filters: []gwv1beta1.HTTPRouteFilter{ - { - Type: gwv1beta1.HTTPRouteFilterRequestHeaderModifier, - RequestHeaderModifier: &gwv1beta1.HTTPHeaderFilter{ - Set: []gwv1beta1.HTTPHeader{ - { - Name: "foo", - Value: "bax", - }, - }, - Add: []gwv1beta1.HTTPHeader{ - { - Name: "arc", - Value: "reactor", - }, - }, - Remove: []string{"remove"}, - }, - }, - { - Type: gwv1beta1.HTTPRouteFilterURLRewrite, - URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ - Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), - Path: &gwv1beta1.HTTPPathModifier{ - Type: gwv1beta1.FullPathHTTPPathModifier, - ReplaceFullPath: common.PointerTo("/foobar"), - }, - }, - }, - - { - Type: gwv1beta1.HTTPRouteFilterURLRewrite, - URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ - Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), - Path: &gwv1beta1.HTTPPathModifier{ - Type: gwv1beta1.PrefixMatchHTTPPathModifier, - ReplacePrefixMatch: common.PointerTo("/foo"), - }, - }, - }, - }, - BackendRefs: []gwv1beta1.HTTPBackendRef{ - { - BackendRef: gwv1beta1.BackendRef{ - BackendObjectReference: gwv1beta1.BackendObjectReference{ - Name: "Service", - Port: common.PointerTo(gwv1beta1.PortNumber(8080)), - }, - Weight: common.PointerTo(int32(-50)), - }, - }, - }, - }, - }, - }, - } - - err = k8sClient.Create(ctx, route) - require.NoError(t, err) - - return route -} - -func createFunkyCasingFieldsTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { - route := &v1alpha2.TCPRoute{ - TypeMeta: metav1.TypeMeta{ - Kind: "TCPRoute", - APIVersion: "gateway.networking.k8s.io/v1alpha2", - }, - ObjectMeta: metav1.ObjectMeta{ - Name: "tcp-route", - }, - Spec: gwv1alpha2.TCPRouteSpec{ - CommonRouteSpec: gwv1beta1.CommonRouteSpec{ - ParentRefs: []gwv1beta1.ParentReference{ - { - Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), - Name: gwv1beta1.ObjectName(gw.Name), - SectionName: &gw.Spec.Listeners[2].Name, - Port: &gw.Spec.Listeners[2].Port, - }, - }, - }, - Rules: []gwv1alpha2.TCPRouteRule{ - { - BackendRefs: []gwv1beta1.BackendRef{ - { - BackendObjectReference: gwv1beta1.BackendObjectReference{ - Name: "Service", - Port: common.PointerTo(gwv1beta1.PortNumber(25000)), - }, - Weight: common.PointerTo(int32(-50)), - }, - }, - }, - }, - }, - } - - err := k8sClient.Create(ctx, route) - require.NoError(t, err) - - return route -} From 8f474854c4a58e5b11290fb79b8ae434a430962e Mon Sep 17 00:00:00 2001 From: Ganesh S Date: Mon, 12 Jun 2023 15:50:08 -0700 Subject: [PATCH 018/120] Improvement- [NET-189] Added helm inputs for managing audit logs (#2265) * Added helm inputs for managing audit logs * Remove unwanted changes from values --- .changelog/2265.txt | 3 + .../templates/server-config-configmap.yaml | 25 +++- .../test/unit/server-config-configmap.bats | 140 ++++++++++++++++++ charts/consul/values.yaml | 54 +++++++ 4 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 .changelog/2265.txt diff --git a/.changelog/2265.txt b/.changelog/2265.txt new file mode 100644 index 0000000000..1cf6813c94 --- /dev/null +++ b/.changelog/2265.txt @@ -0,0 +1,3 @@ +```release-note:improvement +(Consul Enterprise) Add support to provide inputs via helm for audit log related configuration +``` diff --git a/charts/consul/templates/server-config-configmap.yaml b/charts/consul/templates/server-config-configmap.yaml index 1ad04a42b5..d3a0206afd 100644 --- a/charts/consul/templates/server-config-configmap.yaml +++ b/charts/consul/templates/server-config-configmap.yaml @@ -1,6 +1,6 @@ {{- if (or (and (ne (.Values.server.enabled | toString) "-") .Values.server.enabled) (and (eq (.Values.server.enabled | toString) "-") .Values.global.enabled)) }} {{- if (not (or (eq .Values.server.limits.requestLimits.mode "disabled") (eq .Values.server.limits.requestLimits.mode "permissive") (eq .Values.server.limits.requestLimits.mode "enforce"))) }}{{fail "server.limits.requestLimits.mode must be one of the following values: disabled, permissive, and enforce." }}{{ end -}} - +{{- if and .Values.server.auditLogs.enabled (not .Values.global.acls.manageSystemACLs) }}{{fail "ACLs must be enabled inorder to configure audit logs"}}{{ end -}} # StatefulSet to run the actual Consul server cluster. apiVersion: v1 kind: ConfigMap @@ -187,4 +187,27 @@ data: } } {{- end }} + {{- if and .Values.server.auditLogs.enabled .Values.global.acls.manageSystemACLs }} + audit-logging.json: |- + { + "audit": { + "enabled": "true", + "sink": { + {{- range $index, $element := .Values.server.auditLogs.sinks }} + {{- if ne $index 0 }},{{end}} + "{{ $element.name }}": { + {{- $firstKeyValuePair := false }} + {{- range $k, $v := $element }} + {{- if ne $k "name" }} + {{- if ne $firstKeyValuePair false }},{{end}} + {{- $firstKeyValuePair = true }} + "{{ $k }}": "{{ $v }}" + {{- end }} + {{- end }} + } + {{- end }} + } + } + } + {{- end }} {{- end }} diff --git a/charts/consul/test/unit/server-config-configmap.bats b/charts/consul/test/unit/server-config-configmap.bats index 2c8a83f4ca..d55c10dd3a 100755 --- a/charts/consul/test/unit/server-config-configmap.bats +++ b/charts/consul/test/unit/server-config-configmap.bats @@ -1057,3 +1057,143 @@ load _helpers [ "${actual}" = "100" ] } + +#-------------------------------------------------------------------- +# server.auditLogs + +@test "server/ConfigMap: server.auditLogs is disabled by default" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'server.auditLogs.enabled=false' \ + . | tee /dev/stderr | + yq -r '.data["audit-logging.json"]' | jq -r .audit | tee /dev/stderr) + + [ "${actual}" = "null" ] +} + +@test "server/ConfigMap: server.auditLogs is enabled but ACLs are disabled" { + cd `chart_dir` + run helm template \ + -s templates/server-config-configmap.yaml \ + --set 'server.auditLogs.enabled=true' \ + --set 'server.auditLogs.sinks[0].name=MySink' \ + --set 'server.auditLogs.sinks[0].type=file' \ + --set 'server.auditLogs.sinks[0].format=json' \ + --set 'server.auditLogs.sinks[0].delivery_guarantee=best-effort' \ + --set 'server.auditLogs.sinks[0].rotate_duration=24h' \ + --set 'server.auditLogs.sinks[0].path=/tmp/audit.json' \ + . + + [ "$status" -eq 1 ] + [[ "$output" =~ "ACLs must be enabled inorder to configure audit logs" ]] +} + +@test "server/ConfigMap: server.auditLogs is enabled without sink inputs" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'server.auditLogs.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -r '.data["audit-logging.json"]' | jq -r .audit.sink | tee /dev/stderr) + + [ "${actual}" = "{}" ] +} + +@test "server/ConfigMap: server.auditLogs is enabled with 1 sink input object" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'server.auditLogs.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.auditLogs.sinks[0].name=MySink' \ + --set 'server.auditLogs.sinks[0].type=file' \ + --set 'server.auditLogs.sinks[0].format=json' \ + --set 'server.auditLogs.sinks[0].delivery_guarantee=best-effort' \ + --set 'server.auditLogs.sinks[0].rotate_duration=24h' \ + --set 'server.auditLogs.sinks[0].path=/tmp/audit.json' \ + . | tee /dev/stderr | + yq -r '.data["audit-logging.json"]' | tee /dev/stderr) + + local actual=$(echo $object | jq -r .audit.sink.MySink.path | tee /dev/stderr) + [ "${actual}" = "/tmp/audit.json" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink.delivery_guarantee | tee /dev/stderr) + [ "${actual}" = "best-effort" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink.rotate_duration | tee /dev/stderr) + [ "${actual}" = "24h" ] +} + +@test "server/ConfigMap: server.auditLogs is enabled with 1 sink input object and it does not contain the name attribute" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'server.auditLogs.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.auditLogs.sinks[0].name=MySink' \ + --set 'server.auditLogs.sinks[0].type=file' \ + --set 'server.auditLogs.sinks[0].format=json' \ + --set 'server.auditLogs.sinks[0].delivery_guarantee=best-effort' \ + --set 'server.auditLogs.sinks[0].rotate_duration=24h' \ + --set 'server.auditLogs.sinks[0].path=/tmp/audit.json' \ + . | tee /dev/stderr | + yq -r '.data["audit-logging.json"]' | jq -r .audit.sink.name | tee /dev/stderr) + + [ "${actual}" = "null" ] +} + +@test "server/ConfigMap: server.auditLogs is enabled with multiple sink input objects" { + cd `chart_dir` + local object=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'server.auditLogs.enabled=true' \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.auditLogs.sinks[0].name=MySink1' \ + --set 'server.auditLogs.sinks[0].type=file' \ + --set 'server.auditLogs.sinks[0].format=json' \ + --set 'server.auditLogs.sinks[0].delivery_guarantee=best-effort' \ + --set 'server.auditLogs.sinks[0].rotate_duration=24h' \ + --set 'server.auditLogs.sinks[0].path=/tmp/audit.json' \ + --set 'server.auditLogs.sinks[1].name=MySink2' \ + --set 'server.auditLogs.sinks[1].type=file' \ + --set 'server.auditLogs.sinks[1].format=json' \ + --set 'server.auditLogs.sinks[1].delivery_guarantee=best-effort' \ + --set 'server.auditLogs.sinks[1].rotate_max_files=15' \ + --set 'server.auditLogs.sinks[1].rotate_duration=24h' \ + --set 'server.auditLogs.sinks[1].path=/tmp/audit-2.json' \ + --set 'server.auditLogs.sinks[2].name=MySink3' \ + --set 'server.auditLogs.sinks[2].type=file' \ + --set 'server.auditLogs.sinks[2].format=json' \ + --set 'server.auditLogs.sinks[2].delivery_guarantee=best-effort' \ + --set 'server.auditLogs.sinks[2].rotate_max_files=20' \ + --set 'server.auditLogs.sinks[2].rotate_duration=18h' \ + --set 'server.auditLogs.sinks[2].path=/tmp/audit-3.json' \ + . | tee /dev/stderr | + yq -r '.data["audit-logging.json"]' | tee /dev/stderr) + + local actual=$(echo $object | jq -r .audit.sink.MySink1.path | tee /dev/stderr) + [ "${actual}" = "/tmp/audit.json" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink3.path | tee /dev/stderr) + [ "${actual}" = "/tmp/audit-3.json" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink2.path | tee /dev/stderr) + [ "${actual}" = "/tmp/audit-2.json" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink1.name | tee /dev/stderr) + [ "${actual}" = "null" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink3.delivery_guarantee | tee /dev/stderr) + [ "${actual}" = "best-effort" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink2.rotate_duration | tee /dev/stderr) + [ "${actual}" = "24h" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink1.format | tee /dev/stderr) + [ "${actual}" = "json" ] + + local actual=$(echo $object | jq -r .audit.sink.MySink3.type | tee /dev/stderr) + [ "${actual}" = "file" ] +} \ No newline at end of file diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 0e325ca66c..6514fde75a 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -1144,6 +1144,60 @@ server: # @type: string caCert: null + # [Enterprise Only] Added in Consul 1.8, the audit object allow users to enable auditing + # and configure a sink and filters for their audit logs. Please refer to + # [audit logs](https://developer.hashicorp.com/consul/docs/enterprise/audit-logging) documentation + # for further information. + auditLogs: + # Controls whether Consul logs out each time a user performs an operation. + # global.acls.manageSystemACLs must be enabled to use this feature. + enabled: false + + # A single entry of the sink object provides configuration for the destination to which Consul + # will log auditing events. + # + # Example: + # + # ```yaml + # sinks: + # - name: My Sink + # type: file + # format: json + # path: /tmp/audit.json + # delivery_guarantee: best-effort + # rotate_duration: 24h + # rotate_max_files: 15 + # rotate_bytes: 25165824 + # + # ``` + # + # The sink object supports the following keys: + # + # - `name` - Name of the sink. + # + # - `type` - Type specifies what kind of sink this is. Currently only file sinks are available + # + # - `format` - Format specifies what format the events will be emitted with. Currently only `json` + # events are emitted. + # + # - `path` - The directory and filename to write audit events to. + # + # - `delivery_guarantee` - Specifies the rules governing how audit events are written. Consul + # only supports `best-effort` event delivery. + # + # - `mode` - The permissions to set on the audit log files. + # + # - `rotate_duration` - Specifies the interval by which the system rotates to a new log file. + # At least one of `rotate_duration` or `rotate_bytes` must be configured to enable audit logging. + # + # - `rotate_bytes` - Specifies how large an individual log file can grow before Consul rotates to a new file. + # At least one of rotate_bytes or rotate_duration must be configured to enable audit logging. + # + # - `rotate_max_files` - Defines the limit that Consul should follow before it deletes old log files. + # + # @type: array + sinks: [] + # Settings for potentially limiting timeouts, rate limiting on clients as well # as servers, and other settings to limit exposure too many requests, requests # waiting for too long, and other runtime considerations. From fc40d5e5d09087818c3ee860f6c47c80c957d789 Mon Sep 17 00:00:00 2001 From: Eric Haberkorn Date: Tue, 13 Jun 2023 11:28:28 -0400 Subject: [PATCH 019/120] Set Consul service instance localities from K8s node labels (#2346) --- .changelog/2346.txt | 3 ++ .../endpoints/endpoints_controller.go | 20 ++++++++ .../endpoints/endpoints_controller_test.go | 48 ++++++++++++++++++- 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 .changelog/2346.txt diff --git a/.changelog/2346.txt b/.changelog/2346.txt new file mode 100644 index 0000000000..fb062ee0fb --- /dev/null +++ b/.changelog/2346.txt @@ -0,0 +1,3 @@ +```release-note:feature +Set locality on services registered with connect-inject. +``` diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go index eeaeeab485..7b236792ab 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go @@ -318,6 +318,20 @@ func (r *Controller) registerServicesAndHealthCheck(apiClient *api.Client, pod c return nil } +func parseLocality(node corev1.Node) *api.Locality { + region := node.Labels[corev1.LabelTopologyRegion] + zone := node.Labels[corev1.LabelTopologyZone] + + if region == "" { + return nil + } + + return &api.Locality{ + Region: region, + Zone: zone, + } +} + // registerGateway creates Consul registrations for the Connect Gateways and registers them with Consul. // It also upserts a Kubernetes health check for the service based on whether the endpoint address is ready. func (r *Controller) registerGateway(apiClient *api.Client, pod corev1.Pod, serviceEndpoints corev1.Endpoints, healthStatus string, endpointAddressMap map[string]bool) error { @@ -405,6 +419,11 @@ func (r *Controller) createServiceRegistrations(pod corev1.Pod, serviceEndpoints } } + var node corev1.Node + // Ignore errors because we don't want failures to block running services. + _ = r.Client.Get(context.Background(), types.NamespacedName{Name: pod.Spec.NodeName, Namespace: pod.Namespace}, &node) + locality := parseLocality(node) + // We only want that annotation to be present when explicitly overriding the consul svc name // Otherwise, the Consul service name should equal the Kubernetes Service name. // The service name in Consul defaults to the Endpoints object name, and is overridden by the pod @@ -440,6 +459,7 @@ func (r *Controller) createServiceRegistrations(pod corev1.Pod, serviceEndpoints Meta: meta, Namespace: consulNS, Tags: tags, + Locality: locality, } serviceRegistration := &api.CatalogRegistration{ Node: common.ConsulNodeNameFromK8sNode(pod.Spec.NodeName), diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go index acf62b2b0e..ea1ce686d6 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go @@ -1938,6 +1938,17 @@ func TestReconcileCreateEndpoint(t *testing.T) { pod1.Annotations[constants.AnnotationUpstreams] = "upstream1:1234" pod1.Annotations[constants.AnnotationEnableMetrics] = "true" pod1.Annotations[constants.AnnotationPrometheusScrapePort] = "12345" + pod1.Spec.NodeName = "my-node" + node := &corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-node", + Namespace: "default", + Labels: map[string]string{ + corev1.LabelTopologyRegion: "us-west-1", + corev1.LabelTopologyZone: "us-west-1a", + }, + }, + } endpoint := &corev1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "service-created", @@ -1958,7 +1969,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { }, }, } - return []runtime.Object{pod1, endpoint} + return []runtime.Object{pod1, node, endpoint} }, expectedConsulSvcInstances: []*api.CatalogService{ { @@ -1978,6 +1989,10 @@ func TestReconcileCreateEndpoint(t *testing.T) { }, ServiceTags: []string{"abc,123", "pod1"}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, + ServiceLocality: &api.Locality{ + Region: "us-west-1", + Zone: "us-west-1a", + }, }, }, expectedProxySvcInstances: []*api.CatalogService{ @@ -2190,6 +2205,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { require.Equal(t, tt.expectedConsulSvcInstances[i].ServicePort, instance.ServicePort) require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceMeta, instance.ServiceMeta) require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceTags, instance.ServiceTags) + require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceLocality, instance.ServiceLocality) require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceTaggedAddresses, instance.ServiceTaggedAddresses) require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceProxy, instance.ServiceProxy) if tt.nodeMeta != nil { @@ -2236,6 +2252,36 @@ func TestReconcileCreateEndpoint(t *testing.T) { } } +func TestParseLocality(t *testing.T) { + t.Run("no labels", func(t *testing.T) { + n := corev1.Node{} + require.Nil(t, parseLocality(n)) + }) + + t.Run("zone only", func(t *testing.T) { + n := corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + corev1.LabelTopologyZone: "us-west-1a", + }, + }, + } + require.Nil(t, parseLocality(n)) + }) + + t.Run("everything", func(t *testing.T) { + n := corev1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + corev1.LabelTopologyRegion: "us-west-1", + corev1.LabelTopologyZone: "us-west-1a", + }, + }, + } + require.Equal(t, &api.Locality{Region: "us-west-1", Zone: "us-west-1a"}, parseLocality(n)) + }) +} + // Tests updating an Endpoints object. // - Tests updates via the register codepath: // - When an address in an Endpoint is updated, that the corresponding service instance in Consul is updated. From 345f62cec6fe7a3b6e9661e994c24ac5b3333cab Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 13 Jun 2023 11:40:51 -0400 Subject: [PATCH 020/120] fix: use correct flag when translating namespaces (#2353) * fix: use correct flag when translating namespaces * Use non-normalized namespace when deregistering services * Guard against namespace queries when namespaces not enabled in cache --- control-plane/api-gateway/cache/gateway.go | 12 +-- .../api-gateway/common/translation.go | 2 +- .../api-gateway/common/translation_test.go | 73 +++++++++++++++++++ .../controllers/gateway_controller.go | 2 +- 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/control-plane/api-gateway/cache/gateway.go b/control-plane/api-gateway/cache/gateway.go index d8dd37ffac..d1de8dd7cc 100644 --- a/control-plane/api-gateway/cache/gateway.go +++ b/control-plane/api-gateway/cache/gateway.go @@ -18,7 +18,7 @@ import ( ) type GatewayCache struct { - config *consul.Config + config Config serverMgr consul.ServerConnectionManager logger logr.Logger @@ -35,7 +35,7 @@ type GatewayCache struct { func NewGatewayCache(ctx context.Context, config Config) *GatewayCache { return &GatewayCache{ - config: config.ConsulClientConfig, + config: config, serverMgr: config.ConsulServerConnMgr, logger: config.Logger, events: make(chan event.GenericEvent), @@ -53,13 +53,13 @@ func (r *GatewayCache) ServicesFor(ref api.ResourceReference) []api.CatalogServi } func (r *GatewayCache) FetchServicesFor(ctx context.Context, ref api.ResourceReference) ([]api.CatalogService, error) { - client, err := consul.NewClientFromConnMgr(r.config, r.serverMgr) + client, err := consul.NewClientFromConnMgr(r.config.ConsulClientConfig, r.serverMgr) if err != nil { return nil, err } opts := &api.QueryOptions{} - if ref.Namespace != "" { + if r.config.NamespacesEnabled && ref.Namespace != "" { opts.Namespace = ref.Namespace } @@ -95,7 +95,7 @@ func (r *GatewayCache) RemoveSubscription(ref api.ResourceReference) { func (r *GatewayCache) subscribeToGateway(ctx context.Context, ref api.ResourceReference, resource types.NamespacedName) { opts := &api.QueryOptions{} - if ref.Namespace != "" { + if r.config.NamespacesEnabled && ref.Namespace != "" { opts.Namespace = ref.Namespace } @@ -117,7 +117,7 @@ func (r *GatewayCache) subscribeToGateway(ctx context.Context, ref api.ResourceR retryBackoff := backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 10) if err := backoff.Retry(func() error { - client, err := consul.NewClientFromConnMgr(r.config, r.serverMgr) + client, err := consul.NewClientFromConnMgr(r.config.ConsulClientConfig, r.serverMgr) if err != nil { return err } diff --git a/control-plane/api-gateway/common/translation.go b/control-plane/api-gateway/common/translation.go index 8644b64716..fd69c8601f 100644 --- a/control-plane/api-gateway/common/translation.go +++ b/control-plane/api-gateway/common/translation.go @@ -50,7 +50,7 @@ func (t ResourceTranslator) NormalizedResourceReference(kind, namespace string, } func (t ResourceTranslator) Namespace(namespace string) string { - return namespaces.ConsulNamespace(namespace, t.EnableK8sMirroring, t.ConsulDestNamespace, t.EnableK8sMirroring, t.MirroringPrefix) + return namespaces.ConsulNamespace(namespace, t.EnableConsulNamespaces, t.ConsulDestNamespace, t.EnableK8sMirroring, t.MirroringPrefix) } // ToAPIGateway translates a kuberenetes API gateway into a Consul APIGateway Config Entry. diff --git a/control-plane/api-gateway/common/translation_test.go b/control-plane/api-gateway/common/translation_test.go index 2c735ad4ac..caa3efbcac 100644 --- a/control-plane/api-gateway/common/translation_test.go +++ b/control-plane/api-gateway/common/translation_test.go @@ -9,11 +9,13 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "fmt" "math/big" "testing" "time" "github.com/google/go-cmp/cmp" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -42,6 +44,77 @@ func (v fakeReferenceValidator) TCPRouteCanReferenceBackend(tcpRoute gwv1alpha2. return true } +func TestTranslator_Namespace(t *testing.T) { + testCases := []struct { + EnableConsulNamespaces bool + ConsulDestNamespace string + EnableK8sMirroring bool + MirroringPrefix string + Input, ExpectedOutput string + }{ + { + EnableConsulNamespaces: false, + ConsulDestNamespace: "default", + EnableK8sMirroring: false, + MirroringPrefix: "", + Input: "namespace-1", + ExpectedOutput: "", + }, + { + EnableConsulNamespaces: false, + ConsulDestNamespace: "default", + EnableK8sMirroring: true, + MirroringPrefix: "", + Input: "namespace-1", + ExpectedOutput: "", + }, + { + EnableConsulNamespaces: false, + ConsulDestNamespace: "default", + EnableK8sMirroring: true, + MirroringPrefix: "pre-", + Input: "namespace-1", + ExpectedOutput: "", + }, + { + EnableConsulNamespaces: true, + ConsulDestNamespace: "default", + EnableK8sMirroring: false, + MirroringPrefix: "", + Input: "namespace-1", + ExpectedOutput: "default", + }, + { + EnableConsulNamespaces: true, + ConsulDestNamespace: "default", + EnableK8sMirroring: true, + MirroringPrefix: "", + Input: "namespace-1", + ExpectedOutput: "namespace-1", + }, + { + EnableConsulNamespaces: true, + ConsulDestNamespace: "default", + EnableK8sMirroring: true, + MirroringPrefix: "pre-", + Input: "namespace-1", + ExpectedOutput: "pre-namespace-1", + }, + } + + for i, tc := range testCases { + t.Run(fmt.Sprintf("%s_%d", t.Name(), i), func(t *testing.T) { + translator := ResourceTranslator{ + EnableConsulNamespaces: tc.EnableConsulNamespaces, + ConsulDestNamespace: tc.ConsulDestNamespace, + EnableK8sMirroring: tc.EnableK8sMirroring, + MirroringPrefix: tc.MirroringPrefix, + } + assert.Equal(t, tc.ExpectedOutput, translator.Namespace(tc.Input)) + }) + } +} + func TestTranslator_ToAPIGateway(t *testing.T) { t.Parallel() k8sObjectName := "my-k8s-gw" diff --git a/control-plane/api-gateway/controllers/gateway_controller.go b/control-plane/api-gateway/controllers/gateway_controller.go index 97805ccdfb..8569508769 100644 --- a/control-plane/api-gateway/controllers/gateway_controller.go +++ b/control-plane/api-gateway/controllers/gateway_controller.go @@ -212,7 +212,7 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct r.gatewayCache.RemoveSubscription(nonNormalizedConsulKey) // make sure we have deregister all services even if they haven't // hit cache yet - if err := r.deregisterAllServices(ctx, consulKey); err != nil { + if err := r.deregisterAllServices(ctx, nonNormalizedConsulKey); err != nil { log.Error(err, "error deregistering services") return ctrl.Result{}, err } From 285096241e0d5c5b6d53dd8a37889ab3ea5a8af2 Mon Sep 17 00:00:00 2001 From: aahel Date: Tue, 13 Jun 2023 21:36:51 +0530 Subject: [PATCH 021/120] added imagePullPolicy for images in values.yaml (#2310) * added imagePullPolicy for images in values.yaml * fix: renamed pullPolicy key according to image * fixed dafault always in tmpl * changed structure of image in yaml * revert changes * added global imagePullPolicy * fixed typo * added changelog file --- .changelog/2310.txt | 3 +++ .../consul/templates/api-gateway-controller-deployment.yaml | 3 +++ charts/consul/templates/api-gateway-gatewayclassconfig.yaml | 1 + charts/consul/templates/client-daemonset.yaml | 1 + charts/consul/templates/cni-daemonset.yaml | 1 + charts/consul/templates/enterprise-license-job.yaml | 1 + charts/consul/templates/gateway-cleanup-job.yaml | 1 + charts/consul/templates/gateway-resources-job.yaml | 1 + charts/consul/templates/mesh-gateway-deployment.yaml | 2 ++ charts/consul/templates/partition-init-job.yaml | 1 + charts/consul/templates/server-acl-init-cleanup-job.yaml | 1 + charts/consul/templates/server-acl-init-job.yaml | 1 + charts/consul/templates/server-statefulset.yaml | 1 + .../consul/templates/webhook-cert-manager-deployment.yaml | 1 + charts/consul/values.yaml | 6 ++++++ 15 files changed, 25 insertions(+) create mode 100644 .changelog/2310.txt diff --git a/.changelog/2310.txt b/.changelog/2310.txt new file mode 100644 index 0000000000..5e37de44ea --- /dev/null +++ b/.changelog/2310.txt @@ -0,0 +1,3 @@ +```release-note:feature +helm: Added imagePullPolicy global field which can be configured to override the default behaviour. +``` \ No newline at end of file diff --git a/charts/consul/templates/api-gateway-controller-deployment.yaml b/charts/consul/templates/api-gateway-controller-deployment.yaml index 8c5c2fa73e..c942576034 100644 --- a/charts/consul/templates/api-gateway-controller-deployment.yaml +++ b/charts/consul/templates/api-gateway-controller-deployment.yaml @@ -57,6 +57,7 @@ spec: containers: - name: api-gateway-controller image: {{ .Values.apiGateway.image }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} ports: - containerPort: 9090 name: sds @@ -219,6 +220,7 @@ spec: {{- if .Values.global.acls.manageSystemACLs }} - name: copy-consul-bin image: {{ .Values.global.image | quote }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - cp - /bin/consul @@ -256,6 +258,7 @@ spec: {{- end}} {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 8 }} image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} volumeMounts: - mountPath: /consul/login name: consul-data diff --git a/charts/consul/templates/api-gateway-gatewayclassconfig.yaml b/charts/consul/templates/api-gateway-gatewayclassconfig.yaml index ba0e6c63db..8688ee6ae7 100644 --- a/charts/consul/templates/api-gateway-gatewayclassconfig.yaml +++ b/charts/consul/templates/api-gateway-gatewayclassconfig.yaml @@ -65,6 +65,7 @@ spec: image: consulAPIGateway: {{ .Values.apiGateway.image }} envoy: {{ .Values.apiGateway.imageEnvoy }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} {{- if .Values.apiGateway.managedGatewayClass.nodeSelector }} nodeSelector: {{ tpl .Values.apiGateway.managedGatewayClass.nodeSelector . | indent 4 | trim }} diff --git a/charts/consul/templates/client-daemonset.yaml b/charts/consul/templates/client-daemonset.yaml index 09a70b394e..ba19343652 100644 --- a/charts/consul/templates/client-daemonset.yaml +++ b/charts/consul/templates/client-daemonset.yaml @@ -493,6 +493,7 @@ spec: {{- if .Values.global.acls.manageSystemACLs }} - name: client-acl-init image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/cni-daemonset.yaml b/charts/consul/templates/cni-daemonset.yaml index ae04d9e657..33ffb0a77e 100644 --- a/charts/consul/templates/cni-daemonset.yaml +++ b/charts/consul/templates/cni-daemonset.yaml @@ -61,6 +61,7 @@ spec: # This container installs the consul CNI binaries and CNI network config file on each node - name: install-cni image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} securityContext: privileged: true command: diff --git a/charts/consul/templates/enterprise-license-job.yaml b/charts/consul/templates/enterprise-license-job.yaml index 0122690104..2a3fa01d00 100644 --- a/charts/consul/templates/enterprise-license-job.yaml +++ b/charts/consul/templates/enterprise-license-job.yaml @@ -124,6 +124,7 @@ spec: initContainers: - name: ent-license-acl-init image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - "/bin/sh" - "-ec" diff --git a/charts/consul/templates/gateway-cleanup-job.yaml b/charts/consul/templates/gateway-cleanup-job.yaml index 44f032b5fd..e4656916de 100644 --- a/charts/consul/templates/gateway-cleanup-job.yaml +++ b/charts/consul/templates/gateway-cleanup-job.yaml @@ -37,6 +37,7 @@ spec: containers: - name: gateway-cleanup image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/gateway-resources-job.yaml b/charts/consul/templates/gateway-resources-job.yaml index 441e64eb14..ea38d7af32 100644 --- a/charts/consul/templates/gateway-resources-job.yaml +++ b/charts/consul/templates/gateway-resources-job.yaml @@ -37,6 +37,7 @@ spec: containers: - name: gateway-resources image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/mesh-gateway-deployment.yaml b/charts/consul/templates/mesh-gateway-deployment.yaml index 449d6ae492..4150b2bdfd 100644 --- a/charts/consul/templates/mesh-gateway-deployment.yaml +++ b/charts/consul/templates/mesh-gateway-deployment.yaml @@ -121,6 +121,7 @@ spec: initContainers: - name: mesh-gateway-init image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: NAMESPACE valueFrom: @@ -179,6 +180,7 @@ spec: containers: - name: mesh-gateway image: {{ .Values.global.imageConsulDataplane | quote }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} {{- if .Values.meshGateway.resources }} resources: {{- if eq (typeOf .Values.meshGateway.resources) "string" }} diff --git a/charts/consul/templates/partition-init-job.yaml b/charts/consul/templates/partition-init-job.yaml index db73ef783b..b351d10027 100644 --- a/charts/consul/templates/partition-init-job.yaml +++ b/charts/consul/templates/partition-init-job.yaml @@ -81,6 +81,7 @@ spec: containers: - name: partition-init-job image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 10 }} {{- if (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey) }} diff --git a/charts/consul/templates/server-acl-init-cleanup-job.yaml b/charts/consul/templates/server-acl-init-cleanup-job.yaml index 35b0877ab4..3676144b40 100644 --- a/charts/consul/templates/server-acl-init-cleanup-job.yaml +++ b/charts/consul/templates/server-acl-init-cleanup-job.yaml @@ -53,6 +53,7 @@ spec: containers: - name: server-acl-init-cleanup image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/server-acl-init-job.yaml b/charts/consul/templates/server-acl-init-job.yaml index e62db41ec2..e42a073c42 100644 --- a/charts/consul/templates/server-acl-init-job.yaml +++ b/charts/consul/templates/server-acl-init-job.yaml @@ -122,6 +122,7 @@ spec: containers: - name: server-acl-init-job image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 0bde9b881a..0c2eb1bffa 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -225,6 +225,7 @@ spec: initContainers: - name: locality-init image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: NODE_NAME valueFrom: diff --git a/charts/consul/templates/webhook-cert-manager-deployment.yaml b/charts/consul/templates/webhook-cert-manager-deployment.yaml index dd93c039d2..25e382be84 100644 --- a/charts/consul/templates/webhook-cert-manager-deployment.yaml +++ b/charts/consul/templates/webhook-cert-manager-deployment.yaml @@ -50,6 +50,7 @@ spec: -deployment-name={{ template "consul.fullname" . }}-webhook-cert-manager \ -deployment-namespace={{ .Release.Namespace }} image: {{ .Values.global.imageK8S }} + imagePullPolicy: {{ .Values.global.imagePullPolicy }} name: webhook-cert-manager resources: limits: diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 6514fde75a..5c77a27f33 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -52,6 +52,12 @@ global: # Changing the partition name would require an un-install and a re-install with the updated name. # Must be "default" in the server cluster ie the Kubernetes cluster that the Consul server pods are deployed onto. name: "default" + + # Set imagePullPolicy for all images used. This is applies to all the images being used. + # One of "IfNotPresent", "Always", "Never" + # Refer to https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy + # @type: string + imagePullPolicy: "" # The name (and tag) of the Consul Docker image for clients and servers. # This can be overridden per component. This should be pinned to a specific From f2c166fc8c77ad0e103b8ac0dcfe35e81860e97f Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Tue, 13 Jun 2023 12:59:55 -0400 Subject: [PATCH 022/120] [chore]: Pin github action workflows (#2356) --- .github/workflows/build.yml | 6 +++--- .github/workflows/jira-issues.yaml | 6 +++--- .github/workflows/jira-pr.yaml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e46e16c9a3..711c228e11 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -124,7 +124,7 @@ jobs: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Setup go - uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 + uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 with: go-version: ${{ matrix.go }} @@ -193,7 +193,7 @@ jobs: - name: Test rpm package if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} - uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" + uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" with: image: registry.access.redhat.com/ubi9/ubi:latest options: -v ${{ github.workspace }}:/work @@ -218,7 +218,7 @@ jobs: - name: Test debian package if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} - uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" + uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" with: image: ubuntu:latest options: -v ${{ github.workspace }}:/work diff --git a/.github/workflows/jira-issues.yaml b/.github/workflows/jira-issues.yaml index 700803a45f..bddc69c83f 100644 --- a/.github/workflows/jira-issues.yaml +++ b/.github/workflows/jira-issues.yaml @@ -15,7 +15,7 @@ jobs: name: Jira Community Issue sync steps: - name: Login - uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1 + uses: atlassian/gajira-login@ca13f8850ea309cf44a6e4e0c49d9aa48ac3ca4c # v3 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} @@ -72,14 +72,14 @@ jobs: - name: Close ticket if: ( github.event.action == 'closed' || github.event.action == 'deleted' ) && steps.search.outputs.issue - uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 + uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 with: issue: ${{ steps.search.outputs.issue }} transition: "Closed" - name: Reopen ticket if: github.event.action == 'reopened' && steps.search.outputs.issue - uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 + uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 with: issue: ${{ steps.search.outputs.issue }} transition: "To Do" diff --git a/.github/workflows/jira-pr.yaml b/.github/workflows/jira-pr.yaml index a285c4c176..078365ac88 100644 --- a/.github/workflows/jira-pr.yaml +++ b/.github/workflows/jira-pr.yaml @@ -13,7 +13,7 @@ jobs: name: Jira sync steps: - name: Login - uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1 + uses: atlassian/gajira-login@ca13f8850ea309cf44a6e4e0c49d9aa48ac3ca4c # v3 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} @@ -86,14 +86,14 @@ jobs: - name: Close ticket if: ( github.event.action == 'closed' || github.event.action == 'deleted' ) && steps.search.outputs.issue - uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 + uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 with: issue: ${{ steps.search.outputs.issue }} transition: "Closed" - name: Reopen ticket if: github.event.action == 'reopened' && steps.search.outputs.issue - uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 + uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 with: issue: ${{ steps.search.outputs.issue }} transition: "To Do" From 80b1f52437e912349a1c86c19c58e653a607d80d Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 13 Jun 2023 13:14:31 -0400 Subject: [PATCH 023/120] ci: update backport assistant to 0.3.4 (#2365) This brings consul-k8s in line with consul. Most importantly, the backport assistant was updated to automatically assign created PRs to the author of the PR that is being backported. --- .github/workflows/backport.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 7f39b4e5a0..dadde6a651 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -13,7 +13,7 @@ jobs: backport: if: github.event.pull_request.merged runs-on: ubuntu-latest - container: hashicorpdev/backport-assistant:0.3.3 + container: hashicorpdev/backport-assistant:0.3.4 steps: - name: Run Backport Assistant run: backport-assistant backport -merge-method=squash -gh-automerge From e691f464bafe3050360bc4a45fd1adb70b19255f Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Tue, 13 Jun 2023 10:41:16 -0700 Subject: [PATCH 024/120] update changelog based on changes made to 1.2.x (#2348) * update changelog based on changes made to 1.2.x * fixed test cases - enterprise cases were in the OSS test cases --- .changelog/1975.txt | 11 - .changelog/1976.txt | 3 - .changelog/2048.txt | 3 + .changelog/2075.txt | 3 + .changelog/2086.txt | 3 + .changelog/2097.txt | 3 + .changelog/2102.txt | 9 + .changelog/2165.txt | 3 + .../configentry_controller_ent_test.go | 313 ++++++++++++++++++ .../configentry_controller_test.go | 313 ------------------ 10 files changed, 337 insertions(+), 327 deletions(-) delete mode 100644 .changelog/1975.txt delete mode 100644 .changelog/1976.txt create mode 100644 .changelog/2048.txt create mode 100644 .changelog/2075.txt create mode 100644 .changelog/2086.txt create mode 100644 .changelog/2097.txt create mode 100644 .changelog/2165.txt diff --git a/.changelog/1975.txt b/.changelog/1975.txt deleted file mode 100644 index ba26b1ab1e..0000000000 --- a/.changelog/1975.txt +++ /dev/null @@ -1,11 +0,0 @@ -```release-note:security -upgrade to use Go 1.19.6. This resolves vulnerabilities CVE-2022-41724 in crypto/tls and CVE-2022-41723 in net/http. -``` - -```release-note:improvement -cli: update minimum go version for project to 1.19. -``` - -```release-note:improvement -control-plane: update minimum go version for project to 1.19. -``` \ No newline at end of file diff --git a/.changelog/1976.txt b/.changelog/1976.txt deleted file mode 100644 index 65024aa6f9..0000000000 --- a/.changelog/1976.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:security -upgrade to use Go 1.19.6. This resolves vulnerabilities CVE-2022-41724 in crypto/tls and CVE-2022-41723 in net/http. -``` \ No newline at end of file diff --git a/.changelog/2048.txt b/.changelog/2048.txt new file mode 100644 index 0000000000..5796ce2397 --- /dev/null +++ b/.changelog/2048.txt @@ -0,0 +1,3 @@ +```release-note:improvement +helm: add samenessGroup CRD +``` \ No newline at end of file diff --git a/.changelog/2075.txt b/.changelog/2075.txt new file mode 100644 index 0000000000..2f0f0344eb --- /dev/null +++ b/.changelog/2075.txt @@ -0,0 +1,3 @@ +```release-note:improvement +helm: add samenessGroup field to exported services CRD +``` \ No newline at end of file diff --git a/.changelog/2086.txt b/.changelog/2086.txt new file mode 100644 index 0000000000..d4e43a630d --- /dev/null +++ b/.changelog/2086.txt @@ -0,0 +1,3 @@ +```release-note:improvement +helm: add samenessGroup field to service resolver CRD +``` \ No newline at end of file diff --git a/.changelog/2097.txt b/.changelog/2097.txt new file mode 100644 index 0000000000..60e99a8515 --- /dev/null +++ b/.changelog/2097.txt @@ -0,0 +1,3 @@ +```release-note:improvement +helm: add samenessGroup field to source intention CRD +``` \ No newline at end of file diff --git a/.changelog/2102.txt b/.changelog/2102.txt index 59d120f747..7adf361d2d 100644 --- a/.changelog/2102.txt +++ b/.changelog/2102.txt @@ -10,3 +10,12 @@ Also, `golang.org/x/net` has been updated to v0.7.0 to resolve CVEs [CVE-2022-41 ](https://github.com/advisories/GHSA-vvpx-j8f3-3w6h .) ``` + +```release-note:improvement +cli: update minimum go version for project to 1.20. +``` + +```release-note:improvement +control-plane: update minimum go version for project to 1.20. +``` + diff --git a/.changelog/2165.txt b/.changelog/2165.txt new file mode 100644 index 0000000000..15c4bdb1e0 --- /dev/null +++ b/.changelog/2165.txt @@ -0,0 +1,3 @@ +```release-note:improvement +control-plane: add FIPS support +``` \ No newline at end of file diff --git a/control-plane/controllers/configentry_controller_ent_test.go b/control-plane/controllers/configentry_controller_ent_test.go index ab6c70b9ad..14ae477a56 100644 --- a/control-plane/controllers/configentry_controller_ent_test.go +++ b/control-plane/controllers/configentry_controller_ent_test.go @@ -87,6 +87,119 @@ func TestConfigEntryController_createsEntConfigEntry(t *testing.T) { require.Equal(t, "", resource.Members[0].Partition) }, }, + { + kubeKind: "ControlPlaneRequestLimit", + consulKind: capi.RateLimitIPConfig, + configEntryResource: &v1alpha1.ControlPlaneRequestLimit{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: kubeNS, + }, + Spec: v1alpha1.ControlPlaneRequestLimitSpec{ + Mode: "permissive", + ReadWriteRatesConfig: v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ACL: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Catalog: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ConfigEntry: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ConnectCA: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Coordinate: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + DiscoveryChain: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Health: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Intention: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + KV: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Tenancy: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + PreparedQuery: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Session: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Txn: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + }, + }, + reconciler: func(client client.Client, cfg *consul.Config, watcher consul.ServerConnectionManager, logger logr.Logger) testReconciler { + return &ControlPlaneRequestLimitController{ + Client: client, + Log: logger, + ConfigEntryController: &ConfigEntryController{ + ConsulClientConfig: cfg, + ConsulServerConnMgr: watcher, + DatacenterName: datacenterName, + }, + } + }, + compare: func(t *testing.T, consulEntry capi.ConfigEntry) { + resource, ok := consulEntry.(*capi.RateLimitIPConfigEntry) + require.True(t, ok, "cast error") + require.Equal(t, "permissive", resource.Mode) + require.Equal(t, 100.0, resource.ReadRate) + require.Equal(t, 100.0, resource.WriteRate) + require.Equal(t, 100.0, resource.ACL.ReadRate) + require.Equal(t, 100.0, resource.ACL.WriteRate) + require.Equal(t, 100.0, resource.Catalog.ReadRate) + require.Equal(t, 100.0, resource.Catalog.WriteRate) + require.Equal(t, 100.0, resource.ConfigEntry.ReadRate) + require.Equal(t, 100.0, resource.ConfigEntry.WriteRate) + require.Equal(t, 100.0, resource.ConnectCA.ReadRate) + require.Equal(t, 100.0, resource.ConnectCA.WriteRate) + require.Equal(t, 100.0, resource.Coordinate.ReadRate) + require.Equal(t, 100.0, resource.Coordinate.WriteRate) + require.Equal(t, 100.0, resource.DiscoveryChain.ReadRate) + require.Equal(t, 100.0, resource.DiscoveryChain.WriteRate) + require.Equal(t, 100.0, resource.Health.ReadRate) + require.Equal(t, 100.0, resource.Health.WriteRate) + require.Equal(t, 100.0, resource.Intention.ReadRate) + require.Equal(t, 100.0, resource.Intention.WriteRate) + require.Equal(t, 100.0, resource.KV.ReadRate) + require.Equal(t, 100.0, resource.KV.WriteRate) + require.Equal(t, 100.0, resource.Tenancy.ReadRate) + require.Equal(t, 100.0, resource.Tenancy.WriteRate) + require.Equal(t, 100.0, resource.PreparedQuery.ReadRate) + require.Equal(t, 100.0, resource.PreparedQuery.WriteRate) + require.Equal(t, 100.0, resource.Session.ReadRate) + require.Equal(t, 100.0, resource.Session.WriteRate) + require.Equal(t, 100.0, resource.Txn.ReadRate) + require.Equal(t, 100.0, resource.Txn.WriteRate, 100.0) + }, + }, } for _, c := range cases { @@ -191,6 +304,123 @@ func TestConfigEntryController_updatesEntConfigEntry(t *testing.T) { require.Equal(t, "", resource.Members[0].Partition) }, }, + { + kubeKind: "ControlPlaneRequestLimit", + consulKind: capi.RateLimitIPConfig, + configEntryResource: &v1alpha1.ControlPlaneRequestLimit{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: kubeNS, + }, + Spec: v1alpha1.ControlPlaneRequestLimitSpec{ + Mode: "permissive", + ReadWriteRatesConfig: v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ACL: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Catalog: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ConfigEntry: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ConnectCA: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Coordinate: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + DiscoveryChain: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Health: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Intention: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + KV: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Tenancy: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + PreparedQuery: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Session: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Txn: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + }, + }, + reconciler: func(client client.Client, cfg *consul.Config, watcher consul.ServerConnectionManager, logger logr.Logger) testReconciler { + return &ControlPlaneRequestLimitController{ + Client: client, + Log: logger, + ConfigEntryController: &ConfigEntryController{ + ConsulClientConfig: cfg, + ConsulServerConnMgr: watcher, + DatacenterName: datacenterName, + }, + } + }, + updateF: func(resource common.ConfigEntryResource) { + ipRateLimit := resource.(*v1alpha1.ControlPlaneRequestLimit) + ipRateLimit.Spec.Mode = "enforcing" + }, + compare: func(t *testing.T, consulEntry capi.ConfigEntry) { + resource, ok := consulEntry.(*capi.RateLimitIPConfigEntry) + require.True(t, ok, "cast error") + require.Equal(t, "enforcing", resource.Mode) + require.Equal(t, 100.0, resource.ReadRate) + require.Equal(t, 100.0, resource.WriteRate) + require.Equal(t, 100.0, resource.ACL.ReadRate) + require.Equal(t, 100.0, resource.ACL.WriteRate) + require.Equal(t, 100.0, resource.Catalog.ReadRate) + require.Equal(t, 100.0, resource.Catalog.WriteRate) + require.Equal(t, 100.0, resource.ConfigEntry.ReadRate) + require.Equal(t, 100.0, resource.ConfigEntry.WriteRate) + require.Equal(t, 100.0, resource.ConnectCA.ReadRate) + require.Equal(t, 100.0, resource.ConnectCA.WriteRate) + require.Equal(t, 100.0, resource.Coordinate.ReadRate) + require.Equal(t, 100.0, resource.Coordinate.WriteRate) + require.Equal(t, 100.0, resource.DiscoveryChain.ReadRate) + require.Equal(t, 100.0, resource.DiscoveryChain.WriteRate) + require.Equal(t, 100.0, resource.Health.ReadRate) + require.Equal(t, 100.0, resource.Health.WriteRate) + require.Equal(t, 100.0, resource.Intention.ReadRate) + require.Equal(t, 100.0, resource.Intention.WriteRate) + require.Equal(t, 100.0, resource.KV.ReadRate) + require.Equal(t, 100.0, resource.KV.WriteRate) + require.Equal(t, 100.0, resource.Tenancy.ReadRate) + require.Equal(t, 100.0, resource.Tenancy.WriteRate) + require.Equal(t, 100.0, resource.PreparedQuery.ReadRate) + require.Equal(t, 100.0, resource.PreparedQuery.WriteRate) + require.Equal(t, 100.0, resource.Session.ReadRate) + require.Equal(t, 100.0, resource.Session.WriteRate) + require.Equal(t, 100.0, resource.Txn.ReadRate) + require.Equal(t, 100.0, resource.Txn.WriteRate) + }, + }, } for _, c := range cases { @@ -296,6 +526,89 @@ func TestConfigEntryController_deletesEntConfigEntry(t *testing.T) { } }, }, + { + + kubeKind: "ControlPlaneRequestLimit", + consulKind: capi.RateLimitIPConfig, + configEntryResourceWithDeletion: &v1alpha1.ControlPlaneRequestLimit{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: kubeNS, + DeletionTimestamp: &metav1.Time{Time: time.Now()}, + Finalizers: []string{FinalizerName}, + }, + Spec: v1alpha1.ControlPlaneRequestLimitSpec{ + Mode: "permissive", + ReadWriteRatesConfig: v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ACL: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Catalog: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ConfigEntry: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + ConnectCA: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Coordinate: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + DiscoveryChain: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Health: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Intention: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + KV: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Tenancy: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + PreparedQuery: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Session: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + Txn: &v1alpha1.ReadWriteRatesConfig{ + ReadRate: 100.0, + WriteRate: 100.0, + }, + }, + }, + reconciler: func(client client.Client, cfg *consul.Config, watcher consul.ServerConnectionManager, logger logr.Logger) testReconciler { + return &ControlPlaneRequestLimitController{ + Client: client, + Log: logger, + ConfigEntryController: &ConfigEntryController{ + ConsulClientConfig: cfg, + ConsulServerConnMgr: watcher, + DatacenterName: datacenterName, + }, + } + }, + }, } for _, c := range cases { diff --git a/control-plane/controllers/configentry_controller_test.go b/control-plane/controllers/configentry_controller_test.go index 0d5f8af5bf..071d67ca6f 100644 --- a/control-plane/controllers/configentry_controller_test.go +++ b/control-plane/controllers/configentry_controller_test.go @@ -476,119 +476,6 @@ func TestConfigEntryControllers_createsConfigEntry(t *testing.T) { require.Equal(t, "test-issuer", jwt.Issuer) }, }, - { - kubeKind: "ControlPlaneRequestLimit", - consulKind: capi.RateLimitIPConfig, - configEntryResource: &v1alpha1.ControlPlaneRequestLimit{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: kubeNS, - }, - Spec: v1alpha1.ControlPlaneRequestLimitSpec{ - Mode: "permissive", - ReadWriteRatesConfig: v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ACL: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Catalog: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ConfigEntry: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ConnectCA: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Coordinate: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - DiscoveryChain: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Health: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Intention: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - KV: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Tenancy: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - PreparedQuery: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Session: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Txn: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - }, - }, - reconciler: func(client client.Client, cfg *consul.Config, watcher consul.ServerConnectionManager, logger logr.Logger) testReconciler { - return &ControlPlaneRequestLimitController{ - Client: client, - Log: logger, - ConfigEntryController: &ConfigEntryController{ - ConsulClientConfig: cfg, - ConsulServerConnMgr: watcher, - DatacenterName: datacenterName, - }, - } - }, - compare: func(t *testing.T, consulEntry capi.ConfigEntry) { - resource, ok := consulEntry.(*capi.RateLimitIPConfigEntry) - require.True(t, ok, "cast error") - require.Equal(t, "permissive", resource.Mode) - require.Equal(t, 100.0, resource.ReadRate) - require.Equal(t, 100.0, resource.WriteRate) - require.Equal(t, 100.0, resource.ACL.ReadRate) - require.Equal(t, 100.0, resource.ACL.WriteRate) - require.Equal(t, 100.0, resource.Catalog.ReadRate) - require.Equal(t, 100.0, resource.Catalog.WriteRate) - require.Equal(t, 100.0, resource.ConfigEntry.ReadRate) - require.Equal(t, 100.0, resource.ConfigEntry.WriteRate) - require.Equal(t, 100.0, resource.ConnectCA.ReadRate) - require.Equal(t, 100.0, resource.ConnectCA.WriteRate) - require.Equal(t, 100.0, resource.Coordinate.ReadRate) - require.Equal(t, 100.0, resource.Coordinate.WriteRate) - require.Equal(t, 100.0, resource.DiscoveryChain.ReadRate) - require.Equal(t, 100.0, resource.DiscoveryChain.WriteRate) - require.Equal(t, 100.0, resource.Health.ReadRate) - require.Equal(t, 100.0, resource.Health.WriteRate) - require.Equal(t, 100.0, resource.Intention.ReadRate) - require.Equal(t, 100.0, resource.Intention.WriteRate) - require.Equal(t, 100.0, resource.KV.ReadRate) - require.Equal(t, 100.0, resource.KV.WriteRate) - require.Equal(t, 100.0, resource.Tenancy.ReadRate) - require.Equal(t, 100.0, resource.Tenancy.WriteRate) - require.Equal(t, 100.0, resource.PreparedQuery.ReadRate) - require.Equal(t, 100.0, resource.PreparedQuery.WriteRate) - require.Equal(t, 100.0, resource.Session.ReadRate) - require.Equal(t, 100.0, resource.Session.WriteRate) - require.Equal(t, 100.0, resource.Txn.ReadRate) - require.Equal(t, 100.0, resource.Txn.WriteRate, 100.0) - }, - }, } for _, c := range cases { @@ -1116,123 +1003,6 @@ func TestConfigEntryControllers_updatesConfigEntry(t *testing.T) { require.Equal(t, []string{"aud1"}, jwt.Audiences) }, }, - { - kubeKind: "ControlPlaneRequestLimit", - consulKind: capi.RateLimitIPConfig, - configEntryResource: &v1alpha1.ControlPlaneRequestLimit{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: kubeNS, - }, - Spec: v1alpha1.ControlPlaneRequestLimitSpec{ - Mode: "permissive", - ReadWriteRatesConfig: v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ACL: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Catalog: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ConfigEntry: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ConnectCA: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Coordinate: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - DiscoveryChain: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Health: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Intention: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - KV: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Tenancy: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - PreparedQuery: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Session: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Txn: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - }, - }, - reconciler: func(client client.Client, cfg *consul.Config, watcher consul.ServerConnectionManager, logger logr.Logger) testReconciler { - return &ControlPlaneRequestLimitController{ - Client: client, - Log: logger, - ConfigEntryController: &ConfigEntryController{ - ConsulClientConfig: cfg, - ConsulServerConnMgr: watcher, - DatacenterName: datacenterName, - }, - } - }, - updateF: func(resource common.ConfigEntryResource) { - ipRateLimit := resource.(*v1alpha1.ControlPlaneRequestLimit) - ipRateLimit.Spec.Mode = "enforcing" - }, - compare: func(t *testing.T, consulEntry capi.ConfigEntry) { - resource, ok := consulEntry.(*capi.RateLimitIPConfigEntry) - require.True(t, ok, "cast error") - require.Equal(t, "enforcing", resource.Mode) - require.Equal(t, 100.0, resource.ReadRate) - require.Equal(t, 100.0, resource.WriteRate) - require.Equal(t, 100.0, resource.ACL.ReadRate) - require.Equal(t, 100.0, resource.ACL.WriteRate) - require.Equal(t, 100.0, resource.Catalog.ReadRate) - require.Equal(t, 100.0, resource.Catalog.WriteRate) - require.Equal(t, 100.0, resource.ConfigEntry.ReadRate) - require.Equal(t, 100.0, resource.ConfigEntry.WriteRate) - require.Equal(t, 100.0, resource.ConnectCA.ReadRate) - require.Equal(t, 100.0, resource.ConnectCA.WriteRate) - require.Equal(t, 100.0, resource.Coordinate.ReadRate) - require.Equal(t, 100.0, resource.Coordinate.WriteRate) - require.Equal(t, 100.0, resource.DiscoveryChain.ReadRate) - require.Equal(t, 100.0, resource.DiscoveryChain.WriteRate) - require.Equal(t, 100.0, resource.Health.ReadRate) - require.Equal(t, 100.0, resource.Health.WriteRate) - require.Equal(t, 100.0, resource.Intention.ReadRate) - require.Equal(t, 100.0, resource.Intention.WriteRate) - require.Equal(t, 100.0, resource.KV.ReadRate) - require.Equal(t, 100.0, resource.KV.WriteRate) - require.Equal(t, 100.0, resource.Tenancy.ReadRate) - require.Equal(t, 100.0, resource.Tenancy.WriteRate) - require.Equal(t, 100.0, resource.PreparedQuery.ReadRate) - require.Equal(t, 100.0, resource.PreparedQuery.WriteRate) - require.Equal(t, 100.0, resource.Session.ReadRate) - require.Equal(t, 100.0, resource.Session.WriteRate) - require.Equal(t, 100.0, resource.Txn.ReadRate) - require.Equal(t, 100.0, resource.Txn.WriteRate) - }, - }, } for _, c := range cases { @@ -1665,89 +1435,6 @@ func TestConfigEntryControllers_deletesConfigEntry(t *testing.T) { } }, }, - { - - kubeKind: "ControlPlaneRequestLimit", - consulKind: capi.RateLimitIPConfig, - configEntryResourceWithDeletion: &v1alpha1.ControlPlaneRequestLimit{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - Namespace: kubeNS, - DeletionTimestamp: &metav1.Time{Time: time.Now()}, - Finalizers: []string{FinalizerName}, - }, - Spec: v1alpha1.ControlPlaneRequestLimitSpec{ - Mode: "permissive", - ReadWriteRatesConfig: v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ACL: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Catalog: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ConfigEntry: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - ConnectCA: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Coordinate: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - DiscoveryChain: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Health: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Intention: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - KV: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Tenancy: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - PreparedQuery: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Session: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - Txn: &v1alpha1.ReadWriteRatesConfig{ - ReadRate: 100.0, - WriteRate: 100.0, - }, - }, - }, - reconciler: func(client client.Client, cfg *consul.Config, watcher consul.ServerConnectionManager, logger logr.Logger) testReconciler { - return &ControlPlaneRequestLimitController{ - Client: client, - Log: logger, - ConfigEntryController: &ConfigEntryController{ - ConsulClientConfig: cfg, - ConsulServerConnMgr: watcher, - DatacenterName: datacenterName, - }, - } - }, - }, } for _, c := range cases { From 9121afcef8e2738f086b2e2bf76ead4ea4157b95 Mon Sep 17 00:00:00 2001 From: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> Date: Wed, 14 Jun 2023 09:23:46 -0500 Subject: [PATCH 025/120] api-gateway: nightly conformance test action (#2257) * trigger conformance tests nightly, squash * remove extra line * Update nightly-api-gateway-conformance.yml --- .../nightly-api-gateway-conformance.yml | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/nightly-api-gateway-conformance.yml diff --git a/.github/workflows/nightly-api-gateway-conformance.yml b/.github/workflows/nightly-api-gateway-conformance.yml new file mode 100644 index 0000000000..cd63ee8467 --- /dev/null +++ b/.github/workflows/nightly-api-gateway-conformance.yml @@ -0,0 +1,28 @@ +# Dispatch to the consul-k8s-workflows with a nightly cron +name: nightly-api-gateway-conformance +on: + schedule: + # * is a special character in YAML so you have to quote this string + # Run nightly at 12AM UTC/8PM EST/5PM PST. + - cron: '0 0 * * *' + + +# these should be the only settings that you will ever need to change +env: + CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.16-dev # Consul's enterprise version to use in tests + BRANCH: ${{ github.ref_name }} + CONTEXT: "nightly" + +jobs: + api-gateway-conformance: + name: api-gateway-conformance + runs-on: ubuntu-latest + steps: + - uses: benc-uk/workflow-dispatch@798e70c97009500150087d30d9f11c5444830385 # v1.2.2 + name: conformance + with: + workflow: api-gateway-conformance.yml + repo: hashicorp/consul-k8s-workflows + ref: main + token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} + inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' From 3ce33026a35947f4de13261d1a79e1d823fc5c49 Mon Sep 17 00:00:00 2001 From: Eric Haberkorn Date: Thu, 15 Jun 2023 09:12:59 -0400 Subject: [PATCH 026/120] add crds for prioritize by locality (#2357) --- .changelog/2357.txt | 3 + .../templates/crd-serviceresolvers.yaml | 9 +++ .../api/v1alpha1/serviceresolver_types.go | 59 ++++++++++++++++--- .../v1alpha1/serviceresolver_types_test.go | 28 +++++++++ ...consul.hashicorp.com_serviceresolvers.yaml | 9 +++ 5 files changed, 99 insertions(+), 9 deletions(-) create mode 100644 .changelog/2357.txt diff --git a/.changelog/2357.txt b/.changelog/2357.txt new file mode 100644 index 0000000000..7cc35f595a --- /dev/null +++ b/.changelog/2357.txt @@ -0,0 +1,3 @@ +```release-note:feature +Add the `PrioritizeByLocality` field to the `ServiceResolver` CRD. +``` diff --git a/charts/consul/templates/crd-serviceresolvers.yaml b/charts/consul/templates/crd-serviceresolvers.yaml index ed95c15846..99cc1bb090 100644 --- a/charts/consul/templates/crd-serviceresolvers.yaml +++ b/charts/consul/templates/crd-serviceresolvers.yaml @@ -227,6 +227,15 @@ spec: type: integer type: object type: object + prioritizeByLocality: + description: PrioritizeByLocality contains the configuration for + locality aware routing. + properties: + mode: + description: Mode specifies the behavior of PrioritizeByLocality + routing. Valid values are "", "none", and "failover". + type: string + type: object redirect: description: Redirect when configured, all attempts to resolve the service this resolver defines will be substituted for the supplied diff --git a/control-plane/api/v1alpha1/serviceresolver_types.go b/control-plane/api/v1alpha1/serviceresolver_types.go index d00821275d..e5ce3c6fa6 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types.go +++ b/control-plane/api/v1alpha1/serviceresolver_types.go @@ -79,6 +79,16 @@ type ServiceResolverSpec struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty"` + // PrioritizeByLocality controls whether the locality of services within the + // local partition will be used to prioritize connectivity. + PrioritizeByLocality *ServiceResolverPrioritizeByLocality `json:"prioritizeByLocality,omitempty"` +} + +type ServiceResolverPrioritizeByLocality struct { + // Mode specifies the type of prioritization that will be performed + // when selecting nodes in the local partition. + // Valid values are: "" (default "none"), "none", and "failover". + Mode string `json:"mode,omitempty"` } type ServiceResolverRedirect struct { @@ -300,15 +310,16 @@ func (in *ServiceResolver) SyncedConditionStatus() corev1.ConditionStatus { // ToConsul converts the entry into its Consul equivalent struct. func (in *ServiceResolver) ToConsul(datacenter string) capi.ConfigEntry { return &capi.ServiceResolverConfigEntry{ - Kind: in.ConsulKind(), - Name: in.ConsulName(), - DefaultSubset: in.Spec.DefaultSubset, - Subsets: in.Spec.Subsets.toConsul(), - Redirect: in.Spec.Redirect.toConsul(), - Failover: in.Spec.Failover.toConsul(), - ConnectTimeout: in.Spec.ConnectTimeout.Duration, - LoadBalancer: in.Spec.LoadBalancer.toConsul(), - Meta: meta(datacenter), + Kind: in.ConsulKind(), + Name: in.ConsulName(), + DefaultSubset: in.Spec.DefaultSubset, + Subsets: in.Spec.Subsets.toConsul(), + Redirect: in.Spec.Redirect.toConsul(), + Failover: in.Spec.Failover.toConsul(), + ConnectTimeout: in.Spec.ConnectTimeout.Duration, + LoadBalancer: in.Spec.LoadBalancer.toConsul(), + PrioritizeByLocality: in.Spec.PrioritizeByLocality.toConsul(), + Meta: meta(datacenter), } } @@ -338,6 +349,7 @@ func (in *ServiceResolver) Validate(consulMeta common.ConsulMeta) error { } errs = append(errs, in.Spec.Redirect.validate(path.Child("redirect"), consulMeta)...) + errs = append(errs, in.Spec.PrioritizeByLocality.validate(path.Child("prioritizeByLocality"))...) errs = append(errs, in.Spec.Subsets.validate(path.Child("subsets"))...) errs = append(errs, in.Spec.LoadBalancer.validate(path.Child("loadBalancer"))...) errs = append(errs, in.validateEnterprise(consulMeta)...) @@ -520,6 +532,16 @@ func (in *ServiceResolverFailover) toConsul() *capi.ServiceResolverFailover { } } +func (in *ServiceResolverPrioritizeByLocality) toConsul() *capi.ServiceResolverPrioritizeByLocality { + if in == nil { + return nil + } + + return &capi.ServiceResolverPrioritizeByLocality{ + Mode: in.Mode, + } +} + func (in ServiceResolverFailoverTarget) toConsul() capi.ServiceResolverFailoverTarget { return capi.ServiceResolverFailoverTarget{ Service: in.Service, @@ -629,6 +651,25 @@ func (in *ServiceResolverFailover) isEmpty() bool { return in.Service == "" && in.ServiceSubset == "" && in.Namespace == "" && len(in.Datacenters) == 0 && len(in.Targets) == 0 && in.Policy == nil && in.SamenessGroup == "" } +func (in *ServiceResolverPrioritizeByLocality) validate(path *field.Path) field.ErrorList { + var errs field.ErrorList + + if in == nil { + return nil + } + + switch in.Mode { + case "": + case "none": + case "failover": + default: + asJSON, _ := json.Marshal(in) + errs = append(errs, field.Invalid(path, string(asJSON), + "mode must be one of '', 'none', or 'failover'")) + } + return errs +} + func (in *ServiceResolverFailover) validate(path *field.Path, consulMeta common.ConsulMeta) field.ErrorList { var errs field.ErrorList if in.isEmpty() { diff --git a/control-plane/api/v1alpha1/serviceresolver_types_test.go b/control-plane/api/v1alpha1/serviceresolver_types_test.go index d09f0809c8..3a3d5a6016 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types_test.go +++ b/control-plane/api/v1alpha1/serviceresolver_types_test.go @@ -66,6 +66,9 @@ func TestServiceResolver_MatchesConsul(t *testing.T) { Datacenter: "redirect_datacenter", Peer: "redirect_peer", }, + PrioritizeByLocality: &ServiceResolverPrioritizeByLocality{ + Mode: "failover", + }, Failover: map[string]ServiceResolverFailover{ "failover1": { Service: "failover1", @@ -147,6 +150,9 @@ func TestServiceResolver_MatchesConsul(t *testing.T) { Datacenter: "redirect_datacenter", Peer: "redirect_peer", }, + PrioritizeByLocality: &capi.ServiceResolverPrioritizeByLocality{ + Mode: "failover", + }, Failover: map[string]capi.ServiceResolverFailover{ "failover1": { Service: "failover1", @@ -277,6 +283,9 @@ func TestServiceResolver_ToConsul(t *testing.T) { Datacenter: "redirect_datacenter", Partition: "redirect_partition", }, + PrioritizeByLocality: &ServiceResolverPrioritizeByLocality{ + Mode: "none", + }, Failover: map[string]ServiceResolverFailover{ "failover1": { Service: "failover1", @@ -358,6 +367,9 @@ func TestServiceResolver_ToConsul(t *testing.T) { Datacenter: "redirect_datacenter", Partition: "redirect_partition", }, + PrioritizeByLocality: &capi.ServiceResolverPrioritizeByLocality{ + Mode: "none", + }, Failover: map[string]capi.ServiceResolverFailover{ "failover1": { Service: "failover1", @@ -882,6 +894,22 @@ func TestServiceResolver_Validate(t *testing.T) { "spec.failover[failB].namespace: Invalid value: \"namespace-b\": Consul Enterprise namespaces must be enabled to set failover.namespace", }, }, + "prioritize by locality none": { + input: &ServiceResolver{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + }, + Spec: ServiceResolverSpec{ + PrioritizeByLocality: &ServiceResolverPrioritizeByLocality{ + Mode: "bad", + }, + }, + }, + namespacesEnabled: false, + expectedErrMsgs: []string{ + "mode must be one of '', 'none', or 'failover'", + }, + }, } for name, testCase := range cases { t.Run(name, func(t *testing.T) { diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml index 3cd3b37324..ec52c04e05 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml @@ -223,6 +223,15 @@ spec: type: integer type: object type: object + prioritizeByLocality: + description: PrioritizeByLocality contains the configuration for + locality aware routing. + properties: + mode: + description: Mode specifies the behavior of PrioritizeByLocality + routing. Valid values are "", "none", and "failover". + type: string + type: object redirect: description: Redirect when configured, all attempts to resolve the service this resolver defines will be substituted for the supplied From 19d2fb50658fb88ed1bb79149f2929101ee355b9 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Thu, 15 Jun 2023 13:56:41 -0400 Subject: [PATCH 027/120] set everything to correct version (#2342) making scripts more robust and removing changing helm chart --- Makefile | 4 ++++ control-plane/build-support/functions/10-util.sh | 11 +++-------- .../scripts/consul-enterprise-version.sh | 11 +++++++++++ control-plane/build-support/scripts/consul-version.sh | 4 ++++ 4 files changed, 22 insertions(+), 8 deletions(-) create mode 100755 control-plane/build-support/scripts/consul-enterprise-version.sh diff --git a/Makefile b/Makefile index 628b13e2f9..9547fd3547 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ VERSION = $(shell ./control-plane/build-support/scripts/version.sh control-plane/version/version.go) CONSUL_IMAGE_VERSION = $(shell ./control-plane/build-support/scripts/consul-version.sh charts/consul/values.yaml) +CONSUL_ENTERPRISE_IMAGE_VERSION = $(shell ./control-plane/build-support/scripts/consul-enterprise-version.sh charts/consul/values.yaml) CONSUL_DATAPLANE_IMAGE_VERSION = $(shell ./control-plane/build-support/scripts/consul-dataplane-version.sh charts/consul/values.yaml) # ===========> Helm Targets @@ -180,6 +181,9 @@ version: consul-version: @echo $(CONSUL_IMAGE_VERSION) +consul-enterprise-version: + @echo $(CONSUL_ENTERPRISE_IMAGE_VERSION) + consul-dataplane-version: @echo $(CONSUL_DATAPLANE_IMAGE_VERSION) diff --git a/control-plane/build-support/functions/10-util.sh b/control-plane/build-support/functions/10-util.sh index 9ba6c26da9..72ce91720c 100644 --- a/control-plane/build-support/functions/10-util.sh +++ b/control-plane/build-support/functions/10-util.sh @@ -631,13 +631,8 @@ function update_version_helm { sed_i ${SED_EXT} -e "s/(version:[[:space:]]*)[^\"]*/\1${full_version}/g" "${cfile}" sed_i ${SED_EXT} -e "s/(appVersion:[[:space:]]*)[^\"]*/\1${full_consul_version}/g" "${cfile}" sed_i ${SED_EXT} -e "s/(image:.*\/consul-k8s-control-plane:)[^\"]*/image: $4${full_version}/g" "${cfile}" - if ! test -z "$3"; then - sed_i ${SED_EXT} -e "s/(image:.*\/consul:)[^\"]*/image: $6:${full_consul_version}/g" "${cfile}" - sed_i ${SED_EXT} -e "s/(image:.*\/consul:)[^\"]*/image: $6:${full_consul_version}/g" "${vfile}" - else - sed_i ${SED_EXT} -e "s/(image:.*\/consul-enterprise:)[^\"]*/image: $6:${full_consul_version}/g" "${cfile}" - sed_i ${SED_EXT} -e "s/(image:.*\/consul-enterprise:)[^\"]*/image: $6:${full_consul_version}/g" "${vfile}" - fi + sed_i ${SED_EXT} -e "s/(image:.*\/consul:)[^\"]*/image: $6:${full_consul_version}/g" "${cfile}" + sed_i ${SED_EXT} -e "s/(image:.*\/consul:)[^\"]*/image: $6:${full_consul_version}/g" "${vfile}" if test -z "$3"; then sed_i ${SED_EXT} -e "s/(artifacthub.io\/prerelease:[[:space:]]*)[^\"]*/\1false/g" "${cfile}" @@ -774,7 +769,7 @@ function prepare_dev { # * - error echo "prepare_dev: dir:$1 consul-k8s:$5 consul:$6 date:"$3" mode:dev" - set_version "$1" "$5" "$3" "dev" "docker.mirror.hashicorp.services\/hashicorppreview\/consul-k8s-control-plane:" "$6" "docker.mirror.hashicorp.services\/hashicorppreview\/consul-enterprise" + set_version "$1" "$5" "$3" "dev" "docker.mirror.hashicorp.services\/hashicorppreview\/consul-k8s-control-plane:" "$6" "docker.mirror.hashicorp.services\/hashicorppreview\/consul" return 0 } diff --git a/control-plane/build-support/scripts/consul-enterprise-version.sh b/control-plane/build-support/scripts/consul-enterprise-version.sh new file mode 100755 index 0000000000..6b48bb4678 --- /dev/null +++ b/control-plane/build-support/scripts/consul-enterprise-version.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 +FILE=$1 +VERSION=$(yq .global.image $FILE) + +if [[ !"${VERSION}" == *"consul:"* ]]; then + VERSION=$(echo ${VERSION} | sed "s/consul:/consul-enterprise:/g") +fi + +echo "${VERSION}" diff --git a/control-plane/build-support/scripts/consul-version.sh b/control-plane/build-support/scripts/consul-version.sh index e245e2a239..faaed33b20 100755 --- a/control-plane/build-support/scripts/consul-version.sh +++ b/control-plane/build-support/scripts/consul-version.sh @@ -4,4 +4,8 @@ FILE=$1 VERSION=$(yq .global.image $FILE) +if [[ "${VERSION}" == *"consul-enterprise:"* ]]; then + VERSION=$(echo ${VERSION} | sed "s/consul-enterprise:/consul:/g") +fi + echo "${VERSION}" From c4617fcfe573df6c39839c593eef6143bcb047c4 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Thu, 15 Jun 2023 16:29:58 -0400 Subject: [PATCH 028/120] api-gateway: fix cache and service deletion issue (#2377) * Fix cache and service deletion issue * Add comments * add in acceptance test * Fix indentation * Fix unit test for deleting gateway w/ consul services * Remove redundant service deregistration code * Exit loop early once registration is found for service * Fix import blocking * Set status on pods added to test * Apply suggestions from code review * Reduce count of test gateways to 10 from 100 --------- Co-authored-by: Nathan Coleman Co-authored-by: Sarah Alsmiller --- acceptance/go.mod | 3 +- acceptance/go.sum | 2 + .../api_gateway_gatewayclassconfig_test.go | 207 ++++++++++++++++++ control-plane/api-gateway/binding/binder.go | 1 + .../api-gateway/binding/binder_test.go | 25 ++- control-plane/api-gateway/cache/gateway.go | 17 -- 6 files changed, 236 insertions(+), 19 deletions(-) create mode 100644 acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go diff --git a/acceptance/go.mod b/acceptance/go.mod index ddce3e4e5c..59cbbab79f 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -16,6 +16,7 @@ require ( k8s.io/api v0.26.3 k8s.io/apimachinery v0.26.3 k8s.io/client-go v0.26.3 + k8s.io/utils v0.0.0-20230209194617-a36077c30491 sigs.k8s.io/controller-runtime v0.14.6 sigs.k8s.io/gateway-api v0.7.0 ) @@ -30,6 +31,7 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deckarep/golang-set v1.7.1 // indirect github.com/emicklei/go-restful/v3 v3.9.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect @@ -120,7 +122,6 @@ require ( k8s.io/component-base v0.26.3 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect - k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index bd7421de60..578a95b1dd 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -144,6 +144,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ= +github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= diff --git a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go new file mode 100644 index 0000000000..add65b89af --- /dev/null +++ b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go @@ -0,0 +1,207 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package apigateway + +import ( + "context" + "testing" + + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" + "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/stretchr/testify/require" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/utils/pointer" + "sigs.k8s.io/controller-runtime/pkg/client" + gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" +) + +// GatewayClassConfig tests the creation of a gatewayclassconfig object and makes sure that its configuration +// is properly applied to any child gateway objects, namely that the number of gateway instances match the defined +// minInstances,maxInstances and defaultInstances parameters, and that changing the parent gateway does not affect +// the child gateways. +func TestAPIGateway_GatewayClassConfig(t *testing.T) { + ctx := suite.Environment().DefaultContext(t) + cfg := suite.Config() + helmValues := map[string]string{ + "global.logLevel": "trace", + "connectInject.enabled": "true", + } + releaseName := helpers.RandomName() + consulCluster := consul.NewHelmCluster(t, helmValues, ctx, cfg, releaseName) + consulCluster.Create(t) + // Override the default proxy config settings for this test. + consulClient, _ := consulCluster.SetupConsulClient(t, false) + _, _, err := consulClient.ConfigEntries().Set(&api.ProxyConfigEntry{ + Kind: api.ProxyDefaults, + Name: api.ProxyConfigGlobal, + Config: map[string]interface{}{ + "protocol": "http", + }, + }, nil) + require.NoError(t, err) + + k8sClient := ctx.ControllerRuntimeClient(t) + namespace := "gateway-namespace" + + //create clean namespace + err = k8sClient.Create(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + }) + require.NoError(t, err) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + logger.Log(t, "deleting gateway namesapce") + k8sClient.Delete(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + }) + }) + + defaultInstances := pointer.Int32(2) + maxInstances := pointer.Int32(8) + minInstances := pointer.Int32(1) + // create a GatewayClassConfig with configuration set + gatewayClassConfigName := "gateway-class-config" + gatewayClassConfig := &v1alpha1.GatewayClassConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: gatewayClassConfigName, + }, + Spec: v1alpha1.GatewayClassConfigSpec{ + DeploymentSpec: v1alpha1.DeploymentSpec{ + DefaultInstances: defaultInstances, + MaxInstances: maxInstances, + MinInstances: minInstances, + }, + }, + } + logger.Log(t, "creating gateway class config") + err = k8sClient.Create(context.Background(), gatewayClassConfig) + require.NoError(t, err) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + logger.Log(t, "deleting all gateway class configs") + k8sClient.DeleteAllOf(context.Background(), &v1alpha1.GatewayClassConfig{}) + }) + + gatewayParametersRef := &gwv1beta1.ParametersReference{ + Group: gwv1beta1.Group(v1alpha1.ConsulHashicorpGroup), + Kind: gwv1beta1.Kind(v1alpha1.GatewayClassConfigKind), + Name: gatewayClassConfigName, + } + + // create gateway class referencing gateway-class-config + gatewayClassName := "gateway-class" + logger.Log(t, "creating controlled gateway class") + createGatewayClass(t, k8sClient, gatewayClassName, gatewayClassControllerName, gatewayParametersRef) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + logger.Log(t, "deleting all gateway classes") + k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.GatewayClass{}) + }) + + // Create a certificate to reference in listeners + certificateInfo := generateCertificate(t, nil, "certificate.consul.local") + certificateName := "certificate" + certificate := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: certificateName, + Namespace: namespace, + Labels: map[string]string{ + "test-certificate": "true", + }, + }, + Type: corev1.SecretTypeTLS, + Data: map[string][]byte{ + corev1.TLSCertKey: certificateInfo.CertPEM, + corev1.TLSPrivateKeyKey: certificateInfo.PrivateKeyPEM, + }, + } + logger.Log(t, "creating certificate") + err = k8sClient.Create(context.Background(), certificate) + require.NoError(t, err) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8sClient.Delete(context.Background(), certificate) + }) + + // Create gateway referencing gateway class config + gatewayName := "gateway" + logger.Log(t, "creating controlled gateway") + gateway := createGateway(t, k8sClient, gatewayName, namespace, gatewayClassName, certificateName) + // make sure it exists + logger.Log(t, "checking that gateway one is synchronized to Consul") + checkConsulExists(t, consulClient, api.APIGateway, gatewayName) + + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + logger.Log(t, "deleting all gateways") + k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.Gateway{}, client.InNamespace(namespace)) + }) + + // Scenario: Gateway deployment should match the default instances defined on the gateway class config + logger.Log(t, "checking that gateway instances match defined gateway class config") + checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, defaultInstances, gateway) + + //Scenario: Updating the GatewayClassConfig should not affect gateways that have already been created + logger.Log(t, "updating gatewayclassconfig values") + err = k8sClient.Get(context.Background(), types.NamespacedName{Name: gatewayClassConfigName, Namespace: namespace}, gatewayClassConfig) + require.NoError(t, err) + gatewayClassConfig.Spec.DeploymentSpec.DefaultInstances = pointer.Int32(8) + gatewayClassConfig.Spec.DeploymentSpec.MinInstances = pointer.Int32(5) + err = k8sClient.Update(context.Background(), gatewayClassConfig) + require.NoError(t, err) + checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, defaultInstances, gateway) + + //Scenario: gateways should be able to scale independently and not get overridden by the controller unless it's above the max + scale(t, k8sClient, gateway.Name, gateway.Namespace, maxInstances) + checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, maxInstances, gateway) + scale(t, k8sClient, gateway.Name, gateway.Namespace, pointer.Int32(10)) + checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, maxInstances, gateway) + scale(t, k8sClient, gateway.Name, gateway.Namespace, pointer.Int32(0)) + checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, minInstances, gateway) + +} + +func scale(t *testing.T, client client.Client, name, namespace string, scaleTo *int32) { + t.Helper() + + retryCheck(t, 30, func(r *retry.R) { + var deployment appsv1.Deployment + err := client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, &deployment) + require.NoError(r, err) + + deployment.Spec.Replicas = scaleTo + err = client.Update(context.Background(), &deployment) + require.NoError(r, err) + }) +} + +func checkNumberOfInstances(t *testing.T, k8client client.Client, consulClient *api.Client, name, namespace string, wantNumber *int32, gateway *gwv1beta1.Gateway) { + t.Helper() + + retryCheck(t, 30, func(r *retry.R) { + //first check to make sure the number of replicas has been set properly + var deployment appsv1.Deployment + err := k8client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, &deployment) + require.NoError(r, err) + require.EqualValues(r, *wantNumber, *deployment.Spec.Replicas) + + //then check to make sure the number of gateway pods matches the replicas generated + podList := corev1.PodList{} + labels := common.LabelsForGateway(gateway) + err = k8client.List(context.Background(), &podList, client.InNamespace(namespace), client.MatchingLabels(labels)) + require.NoError(r, err) + require.EqualValues(r, *wantNumber, len(podList.Items)) + + services, _, err := consulClient.Catalog().Service(name, "", nil) + require.NoError(r, err) + require.EqualValues(r, *wantNumber, len(services)) + }) +} diff --git a/control-plane/api-gateway/binding/binder.go b/control-plane/api-gateway/binding/binder.go index 28a26985a8..7fbf18d412 100644 --- a/control-plane/api-gateway/binding/binder.go +++ b/control-plane/api-gateway/binding/binder.go @@ -197,6 +197,7 @@ func (b *Binder) Snapshot() *Snapshot { for _, registration := range registrations { if service.ServiceID == registration.Service.ID { found = true + break } } if !found { diff --git a/control-plane/api-gateway/binding/binder_test.go b/control-plane/api-gateway/binding/binder_test.go index a3af702dab..bb30b98f52 100644 --- a/control-plane/api-gateway/binding/binder_test.go +++ b/control-plane/api-gateway/binding/binder_test.go @@ -15,6 +15,7 @@ import ( logrtest "github.com/go-logr/logr/testing" "github.com/google/go-cmp/cmp" + "github.com/hashicorp/consul/api" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -25,7 +26,6 @@ import ( "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" - "github.com/hashicorp/consul/api" ) func init() { @@ -809,6 +809,29 @@ func TestBinder_Registrations(t *testing.T) { {Node: "test", ServiceID: "pod2", Namespace: "namespace1"}, {Node: "test", ServiceID: "pod3", Namespace: "namespace1"}, }, + Pods: []corev1.Pod{ + { + ObjectMeta: metav1.ObjectMeta{Name: "pod1"}, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + Conditions: []corev1.PodCondition{{Type: corev1.PodReady, Status: corev1.ConditionTrue}}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "pod2"}, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + Conditions: []corev1.PodCondition{{Type: corev1.PodReady, Status: corev1.ConditionTrue}}, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "pod3"}, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + Conditions: []corev1.PodCondition{{Type: corev1.PodReady, Status: corev1.ConditionTrue}}, + }, + }, + }, }), expectedDeregistrations: []api.CatalogDeregistration{ {Node: "test", ServiceID: "pod1", Namespace: "namespace1"}, diff --git a/control-plane/api-gateway/cache/gateway.go b/control-plane/api-gateway/cache/gateway.go index d1de8dd7cc..0d79542eec 100644 --- a/control-plane/api-gateway/cache/gateway.go +++ b/control-plane/api-gateway/cache/gateway.go @@ -14,7 +14,6 @@ import ( "github.com/hashicorp/consul-k8s/control-plane/consul" "github.com/hashicorp/consul/api" "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/event" ) type GatewayCache struct { @@ -22,8 +21,6 @@ type GatewayCache struct { serverMgr consul.ServerConnectionManager logger logr.Logger - events chan event.GenericEvent - data map[api.ResourceReference][]api.CatalogService dataMutex sync.RWMutex @@ -38,7 +35,6 @@ func NewGatewayCache(ctx context.Context, config Config) *GatewayCache { config: config, serverMgr: config.ConsulServerConnMgr, logger: config.Logger, - events: make(chan event.GenericEvent), data: make(map[api.ResourceReference][]api.CatalogService), subscribedGateways: make(map[api.ResourceReference]context.CancelFunc), ctx: ctx, @@ -140,18 +136,5 @@ func (r *GatewayCache) subscribeToGateway(ctx context.Context, ref api.ResourceR r.dataMutex.Lock() r.data[common.NormalizeMeta(ref)] = derefed r.dataMutex.Unlock() - - event := event.GenericEvent{ - Object: newConfigEntryObject(resource), - } - - select { - case <-ctx.Done(): - r.dataMutex.Lock() - delete(r.data, ref) - r.dataMutex.Unlock() - return - case r.events <- event: - } } } From 47d40635a33ab8bb86b1d2d3953d2aecf151520b Mon Sep 17 00:00:00 2001 From: Rahul Date: Mon, 19 Jun 2023 10:57:36 +0530 Subject: [PATCH 029/120] Adding support for weighted k8s service (#2293) * Adding support for weighted k8s service * Adding changelog * if per-app weight is 0 then pull the weight to 1 * Addressing review comments * Addressing review comments * Addressing review comments * Comment update * Comment update * Parameterized table test * Parameterized table test * fixing linting issue * fixing linting issue --------- Co-authored-by: srahul3 --- .changelog/2293.txt | 3 + control-plane/catalog/to-consul/annotation.go | 6 + control-plane/catalog/to-consul/resource.go | 41 ++++++ .../catalog/to-consul/resource_test.go | 133 ++++++++++++++++++ 4 files changed, 183 insertions(+) create mode 100644 .changelog/2293.txt diff --git a/.changelog/2293.txt b/.changelog/2293.txt new file mode 100644 index 0000000000..ce6d888bcd --- /dev/null +++ b/.changelog/2293.txt @@ -0,0 +1,3 @@ +```release-note:feature +sync-catalog: add ability to support weighted loadbalancing by service annotation `consul.hashicorp.com/service-weight: ` +``` \ No newline at end of file diff --git a/control-plane/catalog/to-consul/annotation.go b/control-plane/catalog/to-consul/annotation.go index 27e37ca217..edca70b60c 100644 --- a/control-plane/catalog/to-consul/annotation.go +++ b/control-plane/catalog/to-consul/annotation.go @@ -26,4 +26,10 @@ const ( // annotationServiceMetaPrefix is the prefix for setting meta key/value // for a service. The remainder of the key is the meta key. annotationServiceMetaPrefix = "consul.hashicorp.com/service-meta-" + + // annotationServiceWeight is the key of the annotation that determines + // the traffic weight of the service which is spanned over multiple k8s cluster. + // e.g. Service `backend` in k8s cluster `A` receives 25% of the traffic + // compared to same `backend` service in k8s cluster `B`. + annotationServiceWeight = "consul.hashicorp.com/service-weight" ) diff --git a/control-plane/catalog/to-consul/resource.go b/control-plane/catalog/to-consul/resource.go index 6a4e913d80..08aeec8821 100644 --- a/control-plane/catalog/to-consul/resource.go +++ b/control-plane/catalog/to-consul/resource.go @@ -511,6 +511,19 @@ func (t *ServiceResource) generateRegistrations(key string) { r.Service = &rs r.Service.ID = serviceID(r.Service.Service, ip) r.Service.Address = ip + // Adding information about service weight. + // Overrides the existing weight if present. + if weight, ok := svc.Annotations[annotationServiceWeight]; ok && weight != "" { + weightI, err := getServiceWeight(weight) + if err == nil { + r.Service.Weights = consulapi.AgentWeights{ + Passing: weightI, + } + } else { + t.Log.Debug("[generateRegistrations] service weight err: ", err) + } + } + t.consulMap[key] = append(t.consulMap[key], &r) } @@ -547,6 +560,19 @@ func (t *ServiceResource) generateRegistrations(key string) { r.Service.ID = serviceID(r.Service.Service, addr) r.Service.Address = addr + // Adding information about service weight. + // Overrides the existing weight if present. + if weight, ok := svc.Annotations[annotationServiceWeight]; ok && weight != "" { + weightI, err := getServiceWeight(weight) + if err == nil { + r.Service.Weights = consulapi.AgentWeights{ + Passing: weightI, + } + } else { + t.Log.Debug("[generateRegistrations] service weight err: ", err) + } + } + t.consulMap[key] = append(t.consulMap[key], &r) } } @@ -999,3 +1025,18 @@ func (t *ServiceResource) isIngressService(key string) bool { func consulHealthCheckID(k8sNS string, serviceID string) string { return fmt.Sprintf("%s/%s", k8sNS, serviceID) } + +// Calculates the passing service weight. +func getServiceWeight(weight string) (int, error) { + // error validation if the input param is a number. + weightI, err := strconv.Atoi(weight) + if err != nil { + return -1, err + } + + if weightI <= 1 { + return -1, fmt.Errorf("expecting the service annotation %s value to be greater than 1", annotationServiceWeight) + } + + return weightI, nil +} diff --git a/control-plane/catalog/to-consul/resource_test.go b/control-plane/catalog/to-consul/resource_test.go index 3c01088c0d..3b8fb78497 100644 --- a/control-plane/catalog/to-consul/resource_test.go +++ b/control-plane/catalog/to-consul/resource_test.go @@ -56,6 +56,139 @@ func TestServiceResource_createDelete(t *testing.T) { }) } +// Test that Loadbalancer service weight is set from service annotation. +func TestServiceWeight_ingress(t *testing.T) { + t.Parallel() + client := fake.NewSimpleClientset() + syncer := newTestSyncer() + serviceResource := defaultServiceResource(client, syncer) + + // Start the controller + closer := controller.TestControllerRun(&serviceResource) + defer closer() + + // Insert an LB service + svc := lbService("foo", metav1.NamespaceDefault, "1.2.3.4") + svc.Annotations[annotationServiceWeight] = "22" + svc.Status.LoadBalancer.Ingress = append( + svc.Status.LoadBalancer.Ingress, + corev1.LoadBalancerIngress{IP: "3.3.3.3"}, + ) + + svc.Status.LoadBalancer.Ingress = append( + svc.Status.LoadBalancer.Ingress, + corev1.LoadBalancerIngress{IP: "4.4.4.4"}, + ) + + _, err := client.CoreV1().Services(metav1.NamespaceDefault).Create(context.Background(), svc, metav1.CreateOptions{}) + require.NoError(t, err) + + // Verify what we got + retry.Run(t, func(r *retry.R) { + syncer.Lock() + defer syncer.Unlock() + actual := syncer.Registrations + require.Len(r, actual, 3) + require.Equal(r, "foo", actual[1].Service.Service) + require.Equal(r, "3.3.3.3", actual[1].Service.Address) + require.Equal(r, 22, actual[1].Service.Weights.Passing) + require.Equal(r, "foo", actual[2].Service.Service) + require.Equal(r, "4.4.4.4", actual[2].Service.Address) + require.Equal(r, 22, actual[2].Service.Weights.Passing) + require.NotEqual(r, actual[1].Service.ID, actual[2].Service.ID) + }) +} + +// Test that Loadbalancer service weight is set from service annotation. +func TestServiceWeight_externalIP(t *testing.T) { + t.Parallel() + client := fake.NewSimpleClientset() + syncer := newTestSyncer() + serviceResource := defaultServiceResource(client, syncer) + + // Start the controller + closer := controller.TestControllerRun(&serviceResource) + defer closer() + + // Insert an LB service + svc := lbService("foo", metav1.NamespaceDefault, "1.2.3.4") + svc.Annotations[annotationServiceWeight] = "22" + svc.Spec.ExternalIPs = []string{"3.3.3.3", "4.4.4.4"} + + _, err := client.CoreV1().Services(metav1.NamespaceDefault).Create(context.Background(), svc, metav1.CreateOptions{}) + require.NoError(t, err) + + // Verify what we got + retry.Run(t, func(r *retry.R) { + syncer.Lock() + defer syncer.Unlock() + actual := syncer.Registrations + require.Len(r, actual, 2) + require.Equal(r, "foo", actual[0].Service.Service) + require.Equal(r, "3.3.3.3", actual[0].Service.Address) + require.Equal(r, 22, actual[0].Service.Weights.Passing) + require.Equal(r, "foo", actual[1].Service.Service) + require.Equal(r, "4.4.4.4", actual[1].Service.Address) + require.Equal(r, 22, actual[1].Service.Weights.Passing) + require.NotEqual(r, actual[0].Service.ID, actual[1].Service.ID) + }) +} + +// Test service weight. +func TestServiceWeight(t *testing.T) { + t.Parallel() + cases := map[string]struct { + Weight string + ExpectError bool + ExtectedWeight int + }{ + "external-IP": { + Weight: "22", + ExpectError: false, + ExtectedWeight: 22, + }, + "non-int-weight": { + Weight: "non-int", + ExpectError: true, + ExtectedWeight: 0, + }, + "one-weight": { + Weight: "1", + ExpectError: true, + ExtectedWeight: 0, + }, + "zero-weight": { + Weight: "0", + ExpectError: true, + ExtectedWeight: 0, + }, + "negative-weight": { + Weight: "-2", + ExpectError: true, + ExtectedWeight: 0, + }, + "greater-than-100-is-allowed": { + Weight: "1000", + ExpectError: false, + ExtectedWeight: 1000, + }, + } + + for name, c := range cases { + t.Run(name, func(tt *testing.T) { + weightI, err := getServiceWeight(c.Weight) + // Verify what we got + retry.Run(tt, func(r *retry.R) { + if c.ExpectError { + require.Error(r, err) + } else { + require.Equal(r, c.ExtectedWeight, weightI) + } + }) + }) + } +} + // Test that we're default enabled. func TestServiceResource_defaultEnable(t *testing.T) { t.Parallel() From fe4857e34b1eeea5aec9d588cb3c762ca83025a8 Mon Sep 17 00:00:00 2001 From: Bryan Eastes Date: Mon, 19 Jun 2023 06:42:30 -0700 Subject: [PATCH 030/120] Bumping go-discover to the lastest version (#2390) * Bumping go-discover to the lastest version --- .changelog/2390.txt | 3 +++ control-plane/Dockerfile | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 .changelog/2390.txt diff --git a/.changelog/2390.txt b/.changelog/2390.txt new file mode 100644 index 0000000000..a4546bd781 --- /dev/null +++ b/.changelog/2390.txt @@ -0,0 +1,3 @@ +```release-note:security +Update [Go-Discover](https://github.com/hashicorp/go-discover) in the container has been updated to address [CVE-2020-14040](https://github.com/advisories/GHSA-5rcv-m4m3-hfh7) +``` diff --git a/control-plane/Dockerfile b/control-plane/Dockerfile index f401ac8262..c09f5ecf80 100644 --- a/control-plane/Dockerfile +++ b/control-plane/Dockerfile @@ -17,7 +17,7 @@ # go-discover builds the discover binary (which we don't currently publish # either). FROM golang:1.19.2-alpine as go-discover -RUN CGO_ENABLED=0 go install github.com/hashicorp/go-discover/cmd/discover@49f60c093101c9c5f6b04d5b1c80164251a761a6 +RUN CGO_ENABLED=0 go install github.com/hashicorp/go-discover/cmd/discover@214571b6a5309addf3db7775f4ee8cf4d264fd5f # dev copies the binary from a local build # ----------------------------------- From a3c8771b8600f7045c08fccc67013c64e1276ec5 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Mon, 19 Jun 2023 08:43:48 -0700 Subject: [PATCH 031/120] Pin Kind versions on release branches (#2384) * pinned kind configuration for CI tests - created a yaml file with the desired pinned versions - created a script to read the yaml - added a make target which can be used in CI to get the desired kind inputs/config --------- Co-authored-by: Curt Bushko --- Makefile | 15 +++++++++++++-- acceptance/ci-inputs/kind-inputs.yaml | 3 +++ .../build-support/scripts/read-yaml-config.sh | 10 ++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 acceptance/ci-inputs/kind-inputs.yaml create mode 100755 control-plane/build-support/scripts/read-yaml-config.sh diff --git a/Makefile b/Makefile index 9547fd3547..34497b1f07 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,9 @@ VERSION = $(shell ./control-plane/build-support/scripts/version.sh control-plane CONSUL_IMAGE_VERSION = $(shell ./control-plane/build-support/scripts/consul-version.sh charts/consul/values.yaml) CONSUL_ENTERPRISE_IMAGE_VERSION = $(shell ./control-plane/build-support/scripts/consul-enterprise-version.sh charts/consul/values.yaml) CONSUL_DATAPLANE_IMAGE_VERSION = $(shell ./control-plane/build-support/scripts/consul-dataplane-version.sh charts/consul/values.yaml) +KIND_VERSION= $(shell ./control-plane/build-support/scripts/read-yaml-config.sh acceptance/ci-inputs/kind-inputs.yaml .kindVersion) +KIND_NODE_IMAGE= $(shell ./control-plane/build-support/scripts/read-yaml-config.sh acceptance/ci-inputs/kind-inputs.yaml .kindNodeImage) +KUBECTL_VERSION= $(shell ./control-plane/build-support/scripts/read-yaml-config.sh acceptance/ci-inputs/kind-inputs.yaml .kubectlVersion) # ===========> Helm Targets @@ -105,7 +108,6 @@ terraform-fmt: # ===========> CLI Targets - cli-dev: @echo "==> Installing consul-k8s CLI tool for ${GOOS}/${GOARCH}" @cd cli; go build -o ./bin/consul-k8s; cp ./bin/consul-k8s ${GOPATH}/bin/ @@ -114,7 +116,6 @@ cli-fips-dev: @echo "==> Installing consul-k8s CLI tool for ${GOOS}/${GOARCH}" @cd cli; CGO_ENABLED=1 GOEXPERIMENT=boringcrypto go build -o ./bin/consul-k8s -tags "fips"; cp ./bin/consul-k8s ${GOPATH}/bin/ - cli-lint: ## Run linter in the control-plane directory. cd cli; golangci-lint run -c ../.golangci.yml @@ -187,6 +188,16 @@ consul-enterprise-version: consul-dataplane-version: @echo $(CONSUL_DATAPLANE_IMAGE_VERSION) +kind-version: + @echo $(KIND_VERSION) + +kind-node-image: + @echo $(KIND_NODE_IMAGE) + +kubectl-version: + @echo $(KUBECTL_VERSION) + + # ===========> Release Targets diff --git a/acceptance/ci-inputs/kind-inputs.yaml b/acceptance/ci-inputs/kind-inputs.yaml new file mode 100644 index 0000000000..615ff302ba --- /dev/null +++ b/acceptance/ci-inputs/kind-inputs.yaml @@ -0,0 +1,3 @@ +kindVersion: v0.19.0 +kindNodeImage: kindest/node:v1.27.1 +kubectlVersion: v1.27.1 diff --git a/control-plane/build-support/scripts/read-yaml-config.sh b/control-plane/build-support/scripts/read-yaml-config.sh new file mode 100755 index 0000000000..37cfd0cc17 --- /dev/null +++ b/control-plane/build-support/scripts/read-yaml-config.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 +INPUT_FILE=$1 +FIELD=$2 + +VALUE=$(yq $FIELD $INPUT_FILE) + +echo "${VALUE}" From aaa54c26105283690b181ec60d05c993404ea6ac Mon Sep 17 00:00:00 2001 From: "hashicorp-copywrite[bot]" <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Date: Tue, 20 Jun 2023 10:39:41 -0400 Subject: [PATCH 032/120] [COMPLIANCE] Add Copyright and License Headers (#2400) Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> --- acceptance/ci-inputs/kind-inputs.yaml | 3 +++ .../fixtures/bases/static-server-tcp/servicedefaults.yaml | 3 +++ cli/version/fips_build.go | 3 +++ cli/version/non_fips_build.go | 3 +++ control-plane/version/fips_build.go | 3 +++ control-plane/version/non_fips_build.go | 3 +++ 6 files changed, 18 insertions(+) diff --git a/acceptance/ci-inputs/kind-inputs.yaml b/acceptance/ci-inputs/kind-inputs.yaml index 615ff302ba..ba21d2cdaf 100644 --- a/acceptance/ci-inputs/kind-inputs.yaml +++ b/acceptance/ci-inputs/kind-inputs.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + kindVersion: v0.19.0 kindNodeImage: kindest/node:v1.27.1 kubectlVersion: v1.27.1 diff --git a/acceptance/tests/fixtures/bases/static-server-tcp/servicedefaults.yaml b/acceptance/tests/fixtures/bases/static-server-tcp/servicedefaults.yaml index 500051db87..f89765cf6d 100644 --- a/acceptance/tests/fixtures/bases/static-server-tcp/servicedefaults.yaml +++ b/acceptance/tests/fixtures/bases/static-server-tcp/servicedefaults.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceDefaults metadata: diff --git a/cli/version/fips_build.go b/cli/version/fips_build.go index 4d04cc6539..63e0e68883 100644 --- a/cli/version/fips_build.go +++ b/cli/version/fips_build.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + //go:build fips package version diff --git a/cli/version/non_fips_build.go b/cli/version/non_fips_build.go index f72aecae73..ce99575d2c 100644 --- a/cli/version/non_fips_build.go +++ b/cli/version/non_fips_build.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + //go:build !fips package version diff --git a/control-plane/version/fips_build.go b/control-plane/version/fips_build.go index 4d04cc6539..63e0e68883 100644 --- a/control-plane/version/fips_build.go +++ b/control-plane/version/fips_build.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + //go:build fips package version diff --git a/control-plane/version/non_fips_build.go b/control-plane/version/non_fips_build.go index f72aecae73..ce99575d2c 100644 --- a/control-plane/version/non_fips_build.go +++ b/control-plane/version/non_fips_build.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + //go:build !fips package version From 63c76820712082fe7a2e62277843f5891ec68bb9 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Tue, 20 Jun 2023 10:42:55 -0400 Subject: [PATCH 033/120] update consul-dataplane on main to use 1.2-dev (#2325) --- charts/consul/Chart.yaml | 2 +- charts/consul/values.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/consul/Chart.yaml b/charts/consul/Chart.yaml index c55c6be6a2..64d7ed4ed0 100644 --- a/charts/consul/Chart.yaml +++ b/charts/consul/Chart.yaml @@ -20,7 +20,7 @@ annotations: - name: consul-k8s-control-plane image: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.2.0-dev - name: consul-dataplane - image: hashicorp/consul-dataplane:1.1.0 + image: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.2-dev - name: envoy image: envoyproxy/envoy:v1.25.1 artifacthub.io/license: MPL-2.0 diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 5c77a27f33..faf7f5bcdf 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -563,7 +563,7 @@ global: # The name (and tag) of the consul-dataplane Docker image used for the # connect-injected sidecar proxies and mesh, terminating, and ingress gateways. # @default: hashicorp/consul-dataplane: - imageConsulDataplane: "hashicorppreview/consul-dataplane:1.1-dev" + imageConsulDataplane: "docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.2-dev" # Configuration for running this Helm chart on the Red Hat OpenShift platform. # This Helm chart currently supports OpenShift v4.x+. From 4141f6f1d35af6bc4802bb820c8d16455fbf9ed9 Mon Sep 17 00:00:00 2001 From: Paul Glass Date: Tue, 20 Jun 2023 09:53:04 -0500 Subject: [PATCH 034/120] Acceptance test for permissive mTLS (#2378) --- .../tests/connect/permissive_mtls_test.go | 94 +++++++++++++++++++ .../mesh-config-permissive-allowed.yaml | 6 ++ ...ice-defaults-static-server-permissive.yaml | 7 ++ ...service-defaults-static-server-strict.yaml | 7 ++ 4 files changed, 114 insertions(+) create mode 100644 acceptance/tests/connect/permissive_mtls_test.go create mode 100644 acceptance/tests/fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml create mode 100644 acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml create mode 100644 acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-strict.yaml diff --git a/acceptance/tests/connect/permissive_mtls_test.go b/acceptance/tests/connect/permissive_mtls_test.go new file mode 100644 index 0000000000..f0a55779ee --- /dev/null +++ b/acceptance/tests/connect/permissive_mtls_test.go @@ -0,0 +1,94 @@ +package connect + +import ( + "context" + "testing" + + "github.com/hashicorp/consul-k8s/acceptance/framework/config" + "github.com/hashicorp/consul-k8s/acceptance/framework/connhelper" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestConnectInject_PermissiveMTLS(t *testing.T) { + cfg := suite.Config() + if !cfg.EnableTransparentProxy { + t.Skipf("skipping this because -enable-transparent-proxy is not set") + } + + ctx := suite.Environment().DefaultContext(t) + + releaseName := helpers.RandomName() + connHelper := connhelper.ConnectHelper{ + ClusterKind: consul.Helm, + Secure: true, + ReleaseName: releaseName, + Ctx: ctx, + Cfg: cfg, + } + connHelper.Setup(t) + connHelper.Install(t) + + deployNonMeshClient(t, connHelper) + deployStaticServer(t, cfg, connHelper) + + kubectlOpts := connHelper.Ctx.KubectlOptions(t) + logger.Logf(t, "Check that incoming non-mTLS connection fails in MutualTLSMode = strict") + k8s.CheckStaticServerConnectionFailing(t, kubectlOpts, "static-client", "http://static-server") + + logger.Log(t, "Set allowEnablingPermissiveMutualTLS = true") + writeCrd(t, connHelper, "../fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml") + + logger.Log(t, "Set mutualTLSMode = permissive for static-server") + writeCrd(t, connHelper, "../fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml") + + logger.Log(t, "Check that incoming mTLS connection is successful in MutualTLSMode = permissive") + k8s.CheckStaticServerConnectionSuccessful(t, kubectlOpts, "static-client", "http://static-server") +} + +func deployNonMeshClient(t *testing.T, ch connhelper.ConnectHelper) { + t.Helper() + + logger.Log(t, "Creating static-client deployment with connect-inject=false") + k8s.DeployKustomize(t, ch.Ctx.KubectlOptions(t), ch.Cfg.NoCleanupOnFailure, ch.Cfg.DebugDirectory, "../fixtures/bases/static-client") + requirePodContainers(t, ch, "app=static-client", 1) +} + +func deployStaticServer(t *testing.T, cfg *config.TestConfig, ch connhelper.ConnectHelper) { + t.Helper() + + logger.Log(t, "Creating static-server deployment with connect-inject=true") + k8s.DeployKustomize(t, ch.Ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + requirePodContainers(t, ch, "app=static-server", 2) +} + +func writeCrd(t *testing.T, ch connhelper.ConnectHelper, path string) { + t.Helper() + + t.Cleanup(func() { + _, _ = k8s.RunKubectlAndGetOutputE(t, ch.Ctx.KubectlOptions(t), "delete", "-f", path) + }) + + _, err := k8s.RunKubectlAndGetOutputE(t, ch.Ctx.KubectlOptions(t), "apply", "-f", path) + require.NoError(t, err) +} + +func requirePodContainers(t *testing.T, ch connhelper.ConnectHelper, selector string, nContainers int) { + t.Helper() + + opts := ch.Ctx.KubectlOptions(t) + client := ch.Ctx.KubernetesClient(t) + retry.Run(t, func(r *retry.R) { + podList, err := client.CoreV1(). + Pods(opts.Namespace). + List(context.Background(), metav1.ListOptions{LabelSelector: selector}) + require.NoError(r, err) + require.Len(r, podList.Items, 1) + require.Len(r, podList.Items[0].Spec.Containers, nContainers) + }) +} diff --git a/acceptance/tests/fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml b/acceptance/tests/fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml new file mode 100644 index 0000000000..944792588a --- /dev/null +++ b/acceptance/tests/fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml @@ -0,0 +1,6 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: Mesh +metadata: + name: mesh +spec: + allowEnablingPermissiveMutualTLS: true diff --git a/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml b/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml new file mode 100644 index 0000000000..6fd335b361 --- /dev/null +++ b/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml @@ -0,0 +1,7 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceDefaults +metadata: + name: static-server + namespace: default +spec: + mutualTLSMode: "permissive" diff --git a/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-strict.yaml b/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-strict.yaml new file mode 100644 index 0000000000..e47ae7aa5d --- /dev/null +++ b/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-strict.yaml @@ -0,0 +1,7 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceDefaults +metadata: + name: static-server + namespace: default +spec: + mutualTLSMode: "strict" From 08534e3454b6621bc654abc08a64a4720e8a9760 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Wed, 21 Jun 2023 16:01:15 -0400 Subject: [PATCH 035/120] Revert "added imagePullPolicy for images in values.yaml (#2310)" (#2415) This reverts commit 285096241e0d5c5b6d53dd8a37889ab3ea5a8af2. --- .changelog/2310.txt | 3 --- .../consul/templates/api-gateway-controller-deployment.yaml | 3 --- charts/consul/templates/api-gateway-gatewayclassconfig.yaml | 1 - charts/consul/templates/client-daemonset.yaml | 1 - charts/consul/templates/cni-daemonset.yaml | 1 - charts/consul/templates/enterprise-license-job.yaml | 1 - charts/consul/templates/gateway-cleanup-job.yaml | 1 - charts/consul/templates/gateway-resources-job.yaml | 1 - charts/consul/templates/mesh-gateway-deployment.yaml | 2 -- charts/consul/templates/partition-init-job.yaml | 1 - charts/consul/templates/server-acl-init-cleanup-job.yaml | 1 - charts/consul/templates/server-acl-init-job.yaml | 1 - charts/consul/templates/server-statefulset.yaml | 1 - .../consul/templates/webhook-cert-manager-deployment.yaml | 1 - charts/consul/values.yaml | 6 ------ 15 files changed, 25 deletions(-) delete mode 100644 .changelog/2310.txt diff --git a/.changelog/2310.txt b/.changelog/2310.txt deleted file mode 100644 index 5e37de44ea..0000000000 --- a/.changelog/2310.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -helm: Added imagePullPolicy global field which can be configured to override the default behaviour. -``` \ No newline at end of file diff --git a/charts/consul/templates/api-gateway-controller-deployment.yaml b/charts/consul/templates/api-gateway-controller-deployment.yaml index c942576034..8c5c2fa73e 100644 --- a/charts/consul/templates/api-gateway-controller-deployment.yaml +++ b/charts/consul/templates/api-gateway-controller-deployment.yaml @@ -57,7 +57,6 @@ spec: containers: - name: api-gateway-controller image: {{ .Values.apiGateway.image }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} ports: - containerPort: 9090 name: sds @@ -220,7 +219,6 @@ spec: {{- if .Values.global.acls.manageSystemACLs }} - name: copy-consul-bin image: {{ .Values.global.image | quote }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - cp - /bin/consul @@ -258,7 +256,6 @@ spec: {{- end}} {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 8 }} image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} volumeMounts: - mountPath: /consul/login name: consul-data diff --git a/charts/consul/templates/api-gateway-gatewayclassconfig.yaml b/charts/consul/templates/api-gateway-gatewayclassconfig.yaml index 8688ee6ae7..ba0e6c63db 100644 --- a/charts/consul/templates/api-gateway-gatewayclassconfig.yaml +++ b/charts/consul/templates/api-gateway-gatewayclassconfig.yaml @@ -65,7 +65,6 @@ spec: image: consulAPIGateway: {{ .Values.apiGateway.image }} envoy: {{ .Values.apiGateway.imageEnvoy }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} {{- if .Values.apiGateway.managedGatewayClass.nodeSelector }} nodeSelector: {{ tpl .Values.apiGateway.managedGatewayClass.nodeSelector . | indent 4 | trim }} diff --git a/charts/consul/templates/client-daemonset.yaml b/charts/consul/templates/client-daemonset.yaml index ba19343652..09a70b394e 100644 --- a/charts/consul/templates/client-daemonset.yaml +++ b/charts/consul/templates/client-daemonset.yaml @@ -493,7 +493,6 @@ spec: {{- if .Values.global.acls.manageSystemACLs }} - name: client-acl-init image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/cni-daemonset.yaml b/charts/consul/templates/cni-daemonset.yaml index 33ffb0a77e..ae04d9e657 100644 --- a/charts/consul/templates/cni-daemonset.yaml +++ b/charts/consul/templates/cni-daemonset.yaml @@ -61,7 +61,6 @@ spec: # This container installs the consul CNI binaries and CNI network config file on each node - name: install-cni image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} securityContext: privileged: true command: diff --git a/charts/consul/templates/enterprise-license-job.yaml b/charts/consul/templates/enterprise-license-job.yaml index 2a3fa01d00..0122690104 100644 --- a/charts/consul/templates/enterprise-license-job.yaml +++ b/charts/consul/templates/enterprise-license-job.yaml @@ -124,7 +124,6 @@ spec: initContainers: - name: ent-license-acl-init image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - "/bin/sh" - "-ec" diff --git a/charts/consul/templates/gateway-cleanup-job.yaml b/charts/consul/templates/gateway-cleanup-job.yaml index e4656916de..44f032b5fd 100644 --- a/charts/consul/templates/gateway-cleanup-job.yaml +++ b/charts/consul/templates/gateway-cleanup-job.yaml @@ -37,7 +37,6 @@ spec: containers: - name: gateway-cleanup image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/gateway-resources-job.yaml b/charts/consul/templates/gateway-resources-job.yaml index ea38d7af32..441e64eb14 100644 --- a/charts/consul/templates/gateway-resources-job.yaml +++ b/charts/consul/templates/gateway-resources-job.yaml @@ -37,7 +37,6 @@ spec: containers: - name: gateway-resources image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/mesh-gateway-deployment.yaml b/charts/consul/templates/mesh-gateway-deployment.yaml index 4150b2bdfd..449d6ae492 100644 --- a/charts/consul/templates/mesh-gateway-deployment.yaml +++ b/charts/consul/templates/mesh-gateway-deployment.yaml @@ -121,7 +121,6 @@ spec: initContainers: - name: mesh-gateway-init image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: NAMESPACE valueFrom: @@ -180,7 +179,6 @@ spec: containers: - name: mesh-gateway image: {{ .Values.global.imageConsulDataplane | quote }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} {{- if .Values.meshGateway.resources }} resources: {{- if eq (typeOf .Values.meshGateway.resources) "string" }} diff --git a/charts/consul/templates/partition-init-job.yaml b/charts/consul/templates/partition-init-job.yaml index b351d10027..db73ef783b 100644 --- a/charts/consul/templates/partition-init-job.yaml +++ b/charts/consul/templates/partition-init-job.yaml @@ -81,7 +81,6 @@ spec: containers: - name: partition-init-job image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 10 }} {{- if (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey) }} diff --git a/charts/consul/templates/server-acl-init-cleanup-job.yaml b/charts/consul/templates/server-acl-init-cleanup-job.yaml index 3676144b40..35b0877ab4 100644 --- a/charts/consul/templates/server-acl-init-cleanup-job.yaml +++ b/charts/consul/templates/server-acl-init-cleanup-job.yaml @@ -53,7 +53,6 @@ spec: containers: - name: server-acl-init-cleanup image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/server-acl-init-job.yaml b/charts/consul/templates/server-acl-init-job.yaml index e42a073c42..e62db41ec2 100644 --- a/charts/consul/templates/server-acl-init-job.yaml +++ b/charts/consul/templates/server-acl-init-job.yaml @@ -122,7 +122,6 @@ spec: containers: - name: server-acl-init-job image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 0c2eb1bffa..0bde9b881a 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -225,7 +225,6 @@ spec: initContainers: - name: locality-init image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: NODE_NAME valueFrom: diff --git a/charts/consul/templates/webhook-cert-manager-deployment.yaml b/charts/consul/templates/webhook-cert-manager-deployment.yaml index 25e382be84..dd93c039d2 100644 --- a/charts/consul/templates/webhook-cert-manager-deployment.yaml +++ b/charts/consul/templates/webhook-cert-manager-deployment.yaml @@ -50,7 +50,6 @@ spec: -deployment-name={{ template "consul.fullname" . }}-webhook-cert-manager \ -deployment-namespace={{ .Release.Namespace }} image: {{ .Values.global.imageK8S }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} name: webhook-cert-manager resources: limits: diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index faf7f5bcdf..eff13a24bc 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -52,12 +52,6 @@ global: # Changing the partition name would require an un-install and a re-install with the updated name. # Must be "default" in the server cluster ie the Kubernetes cluster that the Consul server pods are deployed onto. name: "default" - - # Set imagePullPolicy for all images used. This is applies to all the images being used. - # One of "IfNotPresent", "Always", "Never" - # Refer to https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy - # @type: string - imagePullPolicy: "" # The name (and tag) of the Consul Docker image for clients and servers. # This can be overridden per component. This should be pinned to a specific From 883fbdcfa4947cf38dd3e1062c2913021b2545ac Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Thu, 22 Jun 2023 09:22:59 -0700 Subject: [PATCH 036/120] update with new make targets (#2411) - allow configuration of acceptance testing matrices --- Makefile | 11 +++++++++++ .../ci-inputs/aks_acceptance_test_packages.yaml | 3 +++ .../ci-inputs/eks_acceptance_test_packages.yaml | 3 +++ .../ci-inputs/gke_acceptance_test_packages.yaml | 3 +++ .../ci-inputs/kind_acceptance_test_packages.yaml | 6 ++++++ .../build-support/scripts/set_test_package_matrix.sh | 12 ++++++++++++ 6 files changed, 38 insertions(+) create mode 100644 acceptance/ci-inputs/aks_acceptance_test_packages.yaml create mode 100644 acceptance/ci-inputs/eks_acceptance_test_packages.yaml create mode 100644 acceptance/ci-inputs/gke_acceptance_test_packages.yaml create mode 100644 acceptance/ci-inputs/kind_acceptance_test_packages.yaml create mode 100755 control-plane/build-support/scripts/set_test_package_matrix.sh diff --git a/Makefile b/Makefile index 34497b1f07..de35275868 100644 --- a/Makefile +++ b/Makefile @@ -197,6 +197,17 @@ kind-node-image: kubectl-version: @echo $(KUBECTL_VERSION) +kind-test-packages: + @./control-plane/build-support/scripts/set_test_package_matrix.sh "acceptance/ci-inputs/kind_acceptance_test_packages.yaml" + +gke-test-packages: + @./control-plane/build-support/scripts/set_test_package_matrix.sh "acceptance/ci-inputs/gke_acceptance_test_packages.yaml" + +eks-test-packages: + @./control-plane/build-support/scripts/set_test_package_matrix.sh "acceptance/ci-inputs/eks_acceptance_test_packages.yaml" + +aks-test-packages: + @./control-plane/build-support/scripts/set_test_package_matrix.sh "acceptance/ci-inputs/aks_acceptance_test_packages.yaml" # ===========> Release Targets diff --git a/acceptance/ci-inputs/aks_acceptance_test_packages.yaml b/acceptance/ci-inputs/aks_acceptance_test_packages.yaml new file mode 100644 index 0000000000..cef04a3205 --- /dev/null +++ b/acceptance/ci-inputs/aks_acceptance_test_packages.yaml @@ -0,0 +1,3 @@ +- {runner: 0, test-packages: "connect peering snapshot-agent wan-federation"} +- {runner: 1, test-packages: "consul-dns example partitions metrics sync"} +- {runner: 2, test-packages: "basic cli config-entries api-gateway ingress-gateway terminating-gateway vault"} \ No newline at end of file diff --git a/acceptance/ci-inputs/eks_acceptance_test_packages.yaml b/acceptance/ci-inputs/eks_acceptance_test_packages.yaml new file mode 100644 index 0000000000..cef04a3205 --- /dev/null +++ b/acceptance/ci-inputs/eks_acceptance_test_packages.yaml @@ -0,0 +1,3 @@ +- {runner: 0, test-packages: "connect peering snapshot-agent wan-federation"} +- {runner: 1, test-packages: "consul-dns example partitions metrics sync"} +- {runner: 2, test-packages: "basic cli config-entries api-gateway ingress-gateway terminating-gateway vault"} \ No newline at end of file diff --git a/acceptance/ci-inputs/gke_acceptance_test_packages.yaml b/acceptance/ci-inputs/gke_acceptance_test_packages.yaml new file mode 100644 index 0000000000..cef04a3205 --- /dev/null +++ b/acceptance/ci-inputs/gke_acceptance_test_packages.yaml @@ -0,0 +1,3 @@ +- {runner: 0, test-packages: "connect peering snapshot-agent wan-federation"} +- {runner: 1, test-packages: "consul-dns example partitions metrics sync"} +- {runner: 2, test-packages: "basic cli config-entries api-gateway ingress-gateway terminating-gateway vault"} \ No newline at end of file diff --git a/acceptance/ci-inputs/kind_acceptance_test_packages.yaml b/acceptance/ci-inputs/kind_acceptance_test_packages.yaml new file mode 100644 index 0000000000..74991abd76 --- /dev/null +++ b/acceptance/ci-inputs/kind_acceptance_test_packages.yaml @@ -0,0 +1,6 @@ +- {runner: 0, test-packages: "partitions"} +- {runner: 1, test-packages: "peering"} +- {runner: 2, test-packages: "connect snapshot-agent wan-federation"} +- {runner: 3, test-packages: "cli vault metrics"} +- {runner: 4, test-packages: "api-gateway ingress-gateway sync example consul-dns"} +- {runner: 5, test-packages: "config-entries terminating-gateway basic"} \ No newline at end of file diff --git a/control-plane/build-support/scripts/set_test_package_matrix.sh b/control-plane/build-support/scripts/set_test_package_matrix.sh new file mode 100755 index 0000000000..b248cbad07 --- /dev/null +++ b/control-plane/build-support/scripts/set_test_package_matrix.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +INPUT_FILE=$1 + +# convert readable yaml to json for github actions consumption +# do not include any pretty print, print to single line with -I 0 +VALUE=$(yq eval 'select(fileIndex == 0)' "$INPUT_FILE" -o json -I 0) + +echo "$VALUE" \ No newline at end of file From 5b1856e3a26a3b03ac35cc0d5ea58c0ce20e3b80 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Fri, 23 Jun 2023 10:10:35 -0400 Subject: [PATCH 037/120] feat(helm): add configurable server-acl-init and cleanup resource limits (#2416) * feat(helm): add configurable server-acl-init and cleanup resource limits * Apply suggestions from code review Co-authored-by: Ashwin Venkatesh * bugfix yaml path * fix bats test --------- Co-authored-by: Ashwin Venkatesh --- .changelog/2416.txt | 3 +++ .../server-acl-init-cleanup-job.yaml | 9 +++---- .../consul/templates/server-acl-init-job.yaml | 9 +++---- .../unit/server-acl-init-cleanup-job.bats | 24 +++++++++++++++++ .../consul/test/unit/server-acl-init-job.bats | 24 +++++++++++++++++ charts/consul/values.yaml | 27 +++++++++++++++++++ 6 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 .changelog/2416.txt diff --git a/.changelog/2416.txt b/.changelog/2416.txt new file mode 100644 index 0000000000..e261758542 --- /dev/null +++ b/.changelog/2416.txt @@ -0,0 +1,3 @@ +```release-note:feature +helm: Adds `acls.resources` field which can be configured to override the `resource` settings for the `server-acl-init` and `server-acl-init-cleanup` Jobs. +``` diff --git a/charts/consul/templates/server-acl-init-cleanup-job.yaml b/charts/consul/templates/server-acl-init-cleanup-job.yaml index 35b0877ab4..38ecfcf1b0 100644 --- a/charts/consul/templates/server-acl-init-cleanup-job.yaml +++ b/charts/consul/templates/server-acl-init-cleanup-job.yaml @@ -61,13 +61,10 @@ spec: - -log-json={{ .Values.global.logJSON }} - -k8s-namespace={{ .Release.Namespace }} - {{ template "consul.fullname" . }}-server-acl-init + {{- if .Values.global.acls.resources }} resources: - requests: - memory: "50Mi" - cpu: "50m" - limits: - memory: "50Mi" - cpu: "50m" + {{- toYaml .Values.global.acls.resources | nindent 12 }} + {{- end }} {{- if .Values.global.acls.tolerations }} tolerations: {{ tpl .Values.global.acls.tolerations . | indent 8 | trim }} diff --git a/charts/consul/templates/server-acl-init-job.yaml b/charts/consul/templates/server-acl-init-job.yaml index e62db41ec2..27272d0f76 100644 --- a/charts/consul/templates/server-acl-init-job.yaml +++ b/charts/consul/templates/server-acl-init-job.yaml @@ -307,13 +307,10 @@ spec: {{- end }} {{- end }} {{- end }} + {{- if .Values.global.acls.resources }} resources: - requests: - memory: "50Mi" - cpu: "50m" - limits: - memory: "50Mi" - cpu: "50m" + {{- toYaml .Values.global.acls.resources | nindent 10 }} + {{- end }} {{- if .Values.global.acls.tolerations }} tolerations: {{ tpl .Values.global.acls.tolerations . | indent 8 | trim }} diff --git a/charts/consul/test/unit/server-acl-init-cleanup-job.bats b/charts/consul/test/unit/server-acl-init-cleanup-job.bats index 947cfa9b42..bf6a455d0e 100644 --- a/charts/consul/test/unit/server-acl-init-cleanup-job.bats +++ b/charts/consul/test/unit/server-acl-init-cleanup-job.bats @@ -159,3 +159,27 @@ load _helpers [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# resources + +@test "serverACLInitCleanup/Job: resources defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-cleanup-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"50m","memory":"50Mi"},"requests":{"cpu":"50m","memory":"50Mi"}}' ] +} + +@test "serverACLInitCleanup/Job: resources can be overridden" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-cleanup-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.resources.foo=bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/charts/consul/test/unit/server-acl-init-job.bats b/charts/consul/test/unit/server-acl-init-job.bats index 81064c95eb..a0d0950e89 100644 --- a/charts/consul/test/unit/server-acl-init-job.bats +++ b/charts/consul/test/unit/server-acl-init-job.bats @@ -2202,3 +2202,27 @@ load _helpers [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# resources + +@test "serverACLInit/Job: resources defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -rc '.spec.template.spec.containers[0].resources' | tee /dev/stderr) + [ "${actual}" = '{"limits":{"cpu":"50m","memory":"50Mi"},"requests":{"cpu":"50m","memory":"50Mi"}}' ] +} + +@test "serverACLInit/Job: resources can be overridden" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.resources.foo=bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index eff13a24bc..89336e319e 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -430,6 +430,33 @@ global: # @type: string secretKey: null + # The resource requests (CPU, memory, etc.) for the server-acl-init and server-acl-init-cleanup pods. + # This should be a YAML map corresponding to a Kubernetes + # [`ResourceRequirements``](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#resourcerequirements-v1-core) + # object. + # + # Example: + # + # ```yaml + # resources: + # requests: + # memory: '200Mi' + # cpu: '100m' + # limits: + # memory: '200Mi' + # cpu: '100m' + # ``` + # + # @recurse: false + # @type: map + resources: + requests: + memory: "50Mi" + cpu: "50m" + limits: + memory: "50Mi" + cpu: "50m" + # partitionToken references a Vault secret containing the ACL token to be used in non-default partitions. # This value should only be provided in the default partition and only when setting # the `global.secretsBackend.vault.enabled` value to true. From c6c5d521176749cbbb0e302afddd2620853aca7c Mon Sep 17 00:00:00 2001 From: Alvin Huang <17609145+alvin-huang@users.noreply.github.com> Date: Fri, 23 Jun 2023 13:17:07 -0400 Subject: [PATCH 038/120] update redhat registry id (#2337) --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 711c228e11..917456e9d0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -377,7 +377,7 @@ jobs: pkg_name: consul-k8s-control-plane_${{ env.version }} bin_name: consul-k8s-control-plane workdir: control-plane - redhat_tag: quay.io/redhat-isv-containers/6483ed53b430df51b731406c:${{env.version}}-ubi # this is different than the non-FIPS one + redhat_tag: quay.io/redhat-isv-containers/6486b1beabfc4e51588c0416:${{env.version}}-ubi # this is different than the non-FIPS one build-docker-ubi-dockerhub: name: Docker ${{ matrix.arch }} ${{ matrix.fips }} UBI build for DockerHub From f783f7e924cf93e0d39e5113f113dff8eaef4d1a Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Fri, 23 Jun 2023 14:18:58 -0400 Subject: [PATCH 039/120] Fix auditlog config (#2434) --- charts/consul/templates/server-config-configmap.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/consul/templates/server-config-configmap.yaml b/charts/consul/templates/server-config-configmap.yaml index d3a0206afd..7e3d251001 100644 --- a/charts/consul/templates/server-config-configmap.yaml +++ b/charts/consul/templates/server-config-configmap.yaml @@ -191,7 +191,7 @@ data: audit-logging.json: |- { "audit": { - "enabled": "true", + "enabled": true, "sink": { {{- range $index, $element := .Values.server.auditLogs.sinks }} {{- if ne $index 0 }},{{end}} From 79db26379e814694e57e5ddae0cbd5cb76ac03cd Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Fri, 23 Jun 2023 14:48:36 -0400 Subject: [PATCH 040/120] Add acceptance test to test sync + ingress (#2421) --- acceptance/framework/config/config.go | 1 + acceptance/framework/flags/flags.go | 4 + .../tests/fixtures/bases/ingress/ingress.yaml | 23 ++++++ .../fixtures/bases/ingress/kustomization.yaml | 5 ++ acceptance/tests/sync/sync_catalog_test.go | 81 +++++++++++++++++++ 5 files changed, 114 insertions(+) create mode 100644 acceptance/tests/fixtures/bases/ingress/ingress.yaml create mode 100644 acceptance/tests/fixtures/bases/ingress/kustomization.yaml diff --git a/acceptance/framework/config/config.go b/acceptance/framework/config/config.go index 8a5ba7893e..18673ca260 100644 --- a/acceptance/framework/config/config.go +++ b/acceptance/framework/config/config.go @@ -62,6 +62,7 @@ type TestConfig struct { DebugDirectory string UseAKS bool + UseEKS bool UseGKE bool UseKind bool diff --git a/acceptance/framework/flags/flags.go b/acceptance/framework/flags/flags.go index 3b542c5294..fd1831c5e6 100644 --- a/acceptance/framework/flags/flags.go +++ b/acceptance/framework/flags/flags.go @@ -50,6 +50,7 @@ type TestFlags struct { flagDebugDirectory string flagUseAKS bool + flagUseEKS bool flagUseGKE bool flagUseKind bool @@ -121,6 +122,8 @@ func (t *TestFlags) init() { flag.BoolVar(&t.flagUseAKS, "use-aks", false, "If true, the tests will assume they are running against an AKS cluster(s).") + flag.BoolVar(&t.flagUseEKS, "use-eks", false, + "If true, the tests will assume they are running against an EKS cluster(s).") flag.BoolVar(&t.flagUseGKE, "use-gke", false, "If true, the tests will assume they are running against a GKE cluster(s).") flag.BoolVar(&t.flagUseKind, "use-kind", false, @@ -191,6 +194,7 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { NoCleanupOnFailure: t.flagNoCleanupOnFailure, DebugDirectory: tempDir, UseAKS: t.flagUseAKS, + UseEKS: t.flagUseEKS, UseGKE: t.flagUseGKE, UseKind: t.flagUseKind, } diff --git a/acceptance/tests/fixtures/bases/ingress/ingress.yaml b/acceptance/tests/fixtures/bases/ingress/ingress.yaml new file mode 100644 index 0000000000..7632a187d6 --- /dev/null +++ b/acceptance/tests/fixtures/bases/ingress/ingress.yaml @@ -0,0 +1,23 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: test-ingress + annotations: + kubernetes.io/ingress.class: "alb" + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/target-type: ip +spec: + rules: + - http: + paths: + - path: / + pathType: ImplementationSpecific + backend: + service: + name: static-server + port: + number: 80 + host: test.acceptance.com \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/ingress/kustomization.yaml b/acceptance/tests/fixtures/bases/ingress/kustomization.yaml new file mode 100644 index 0000000000..09fd1b7d0b --- /dev/null +++ b/acceptance/tests/fixtures/bases/ingress/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ingress.yaml diff --git a/acceptance/tests/sync/sync_catalog_test.go b/acceptance/tests/sync/sync_catalog_test.go index 7407126580..2ca8b1ee1f 100644 --- a/acceptance/tests/sync/sync_catalog_test.go +++ b/acceptance/tests/sync/sync_catalog_test.go @@ -79,3 +79,84 @@ func TestSyncCatalog(t *testing.T) { }) } } + +// Test that sync catalog works in both the default installation and +// the secure installation when TLS and ACLs are enabled with an Ingress resource. +// The test will create a test service and a pod and will +// wait for the service to be synced *to* consul. +func TestSyncCatalogWithIngress(t *testing.T) { + cfg := suite.Config() + if cfg.EnableCNI { + t.Skipf("skipping because -enable-cni is set and sync catalog is already tested with regular tproxy") + } + if !cfg.UseEKS { + t.Skipf("skipping because -use-eks is not set and the ingress test only runs on EKS") + } + + cases := map[string]struct { + secure bool + }{ + "non-secure": {secure: false}, + "secure": {secure: true}, + } + + for name, c := range cases { + t.Run(name, func(t *testing.T) { + ctx := suite.Environment().DefaultContext(t) + helmValues := map[string]string{ + "syncCatalog.enabled": "true", + "syncCatalog.ingres.enabled": "true", + "global.tls.enabled": strconv.FormatBool(c.secure), + "global.acls.manageSystemACLs": strconv.FormatBool(c.secure), + } + + releaseName := helpers.RandomName() + consulCluster := consul.NewHelmCluster(t, helmValues, ctx, suite.Config(), releaseName) + + logger.Log(t, "creating ingress resource") + retry.Run(t, func(r *retry.R) { + // Retry the kubectl apply because we've seen sporadic + // "connection refused" errors where the mutating webhook + // endpoint fails initially. + out, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-k", "../fixtures/bases/ingress") + require.NoError(r, err, out) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + // Ignore errors here because if the test ran as expected + // the custom resources will have been deleted. + k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-k", "../fixtures/bases/ingress") + }) + }) + + consulCluster.Create(t) + + logger.Log(t, "creating a static-server with a service") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), suite.Config().NoCleanupOnFailure, suite.Config().DebugDirectory, "../fixtures/bases/static-server") + + consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) + + logger.Log(t, "checking that the service has been synced to Consul") + var services map[string][]string + syncedServiceName := fmt.Sprintf("static-server-%s", ctx.KubectlOptions(t).Namespace) + counter := &retry.Counter{Count: 10, Wait: 5 * time.Second} + retry.RunWith(counter, t, func(r *retry.R) { + var err error + services, _, err = consulClient.Catalog().Services(nil) + require.NoError(r, err) + if _, ok := services[syncedServiceName]; !ok { + r.Errorf("service '%s' is not in Consul's list of services %s", syncedServiceName, services) + } + }) + + service, _, err := consulClient.Catalog().Service(syncedServiceName, "", nil) + require.NoError(t, err) + require.Len(t, service, 1) + require.Equal(t, "test.acceptance.com", service[0].Address) + require.Equal(t, []string{"k8s"}, service[0].ServiceTags) + filter := fmt.Sprintf("ServiceID == %q", service[0].ServiceID) + healthChecks, _, err := consulClient.Health().Checks(syncedServiceName, &api.QueryOptions{Filter: filter}) + require.NoError(t, err) + require.Len(t, healthChecks, 1) + require.Equal(t, api.HealthPassing, healthChecks[0].Status) + }) + } +} From c2a149b36242dcfec21fba0dd81655abc91a4a34 Mon Sep 17 00:00:00 2001 From: "hashicorp-copywrite[bot]" <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Date: Mon, 26 Jun 2023 13:43:08 -0400 Subject: [PATCH 041/120] [COMPLIANCE] Add Copyright and License Headers (#2456) Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> --- acceptance/ci-inputs/aks_acceptance_test_packages.yaml | 3 +++ acceptance/ci-inputs/eks_acceptance_test_packages.yaml | 3 +++ acceptance/ci-inputs/gke_acceptance_test_packages.yaml | 3 +++ acceptance/ci-inputs/kind_acceptance_test_packages.yaml | 3 +++ acceptance/tests/connect/permissive_mtls_test.go | 3 +++ .../cases/permissive-mtls/mesh-config-permissive-allowed.yaml | 3 +++ .../service-defaults-static-server-permissive.yaml | 3 +++ .../permissive-mtls/service-defaults-static-server-strict.yaml | 3 +++ 8 files changed, 24 insertions(+) diff --git a/acceptance/ci-inputs/aks_acceptance_test_packages.yaml b/acceptance/ci-inputs/aks_acceptance_test_packages.yaml index cef04a3205..c1f1093200 100644 --- a/acceptance/ci-inputs/aks_acceptance_test_packages.yaml +++ b/acceptance/ci-inputs/aks_acceptance_test_packages.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + - {runner: 0, test-packages: "connect peering snapshot-agent wan-federation"} - {runner: 1, test-packages: "consul-dns example partitions metrics sync"} - {runner: 2, test-packages: "basic cli config-entries api-gateway ingress-gateway terminating-gateway vault"} \ No newline at end of file diff --git a/acceptance/ci-inputs/eks_acceptance_test_packages.yaml b/acceptance/ci-inputs/eks_acceptance_test_packages.yaml index cef04a3205..c1f1093200 100644 --- a/acceptance/ci-inputs/eks_acceptance_test_packages.yaml +++ b/acceptance/ci-inputs/eks_acceptance_test_packages.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + - {runner: 0, test-packages: "connect peering snapshot-agent wan-federation"} - {runner: 1, test-packages: "consul-dns example partitions metrics sync"} - {runner: 2, test-packages: "basic cli config-entries api-gateway ingress-gateway terminating-gateway vault"} \ No newline at end of file diff --git a/acceptance/ci-inputs/gke_acceptance_test_packages.yaml b/acceptance/ci-inputs/gke_acceptance_test_packages.yaml index cef04a3205..c1f1093200 100644 --- a/acceptance/ci-inputs/gke_acceptance_test_packages.yaml +++ b/acceptance/ci-inputs/gke_acceptance_test_packages.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + - {runner: 0, test-packages: "connect peering snapshot-agent wan-federation"} - {runner: 1, test-packages: "consul-dns example partitions metrics sync"} - {runner: 2, test-packages: "basic cli config-entries api-gateway ingress-gateway terminating-gateway vault"} \ No newline at end of file diff --git a/acceptance/ci-inputs/kind_acceptance_test_packages.yaml b/acceptance/ci-inputs/kind_acceptance_test_packages.yaml index 74991abd76..8677b83c4e 100644 --- a/acceptance/ci-inputs/kind_acceptance_test_packages.yaml +++ b/acceptance/ci-inputs/kind_acceptance_test_packages.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + - {runner: 0, test-packages: "partitions"} - {runner: 1, test-packages: "peering"} - {runner: 2, test-packages: "connect snapshot-agent wan-federation"} diff --git a/acceptance/tests/connect/permissive_mtls_test.go b/acceptance/tests/connect/permissive_mtls_test.go index f0a55779ee..1dcc6fe911 100644 --- a/acceptance/tests/connect/permissive_mtls_test.go +++ b/acceptance/tests/connect/permissive_mtls_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package connect import ( diff --git a/acceptance/tests/fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml b/acceptance/tests/fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml index 944792588a..c336a621e7 100644 --- a/acceptance/tests/fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml +++ b/acceptance/tests/fixtures/cases/permissive-mtls/mesh-config-permissive-allowed.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: Mesh metadata: diff --git a/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml b/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml index 6fd335b361..4559570544 100644 --- a/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml +++ b/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-permissive.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceDefaults metadata: diff --git a/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-strict.yaml b/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-strict.yaml index e47ae7aa5d..cf84c73407 100644 --- a/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-strict.yaml +++ b/acceptance/tests/fixtures/cases/permissive-mtls/service-defaults-static-server-strict.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceDefaults metadata: From c83ce0c51d1a1a65eadb30d1cfb516716681dd76 Mon Sep 17 00:00:00 2001 From: Thomas Eckert Date: Mon, 26 Jun 2023 16:31:35 -0400 Subject: [PATCH 042/120] Fix GatewayClassConfig Test Timing Issue (#2409) * Add retryCheckWithWait func * Fix retry timing on GatewayClassConfig test * remove redundant scale, make scale up number max + 1 * NET-4627, fix acceptance tests flake --------- Co-authored-by: Sarah Alsmiller --- .../api_gateway_gatewayclassconfig_test.go | 103 +++++++++--------- .../api-gateway/api_gateway_tenancy_test.go | 6 +- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go index add65b89af..444af6af4d 100644 --- a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go +++ b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go @@ -5,7 +5,9 @@ package apigateway import ( "context" + "fmt" "testing" + "time" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" @@ -29,6 +31,15 @@ import ( // minInstances,maxInstances and defaultInstances parameters, and that changing the parent gateway does not affect // the child gateways. func TestAPIGateway_GatewayClassConfig(t *testing.T) { + var ( + defaultInstances = pointer.Int32(2) + maxInstances = pointer.Int32(3) + minInstances = pointer.Int32(1) + + namespace = "default" + gatewayClassName = "gateway-class" + ) + ctx := suite.Environment().DefaultContext(t) cfg := suite.Config() helmValues := map[string]string{ @@ -38,6 +49,7 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { releaseName := helpers.RandomName() consulCluster := consul.NewHelmCluster(t, helmValues, ctx, cfg, releaseName) consulCluster.Create(t) + // Override the default proxy config settings for this test. consulClient, _ := consulCluster.SetupConsulClient(t, false) _, _, err := consulClient.ConfigEntries().Set(&api.ProxyConfigEntry{ @@ -50,28 +62,8 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { require.NoError(t, err) k8sClient := ctx.ControllerRuntimeClient(t) - namespace := "gateway-namespace" - //create clean namespace - err = k8sClient.Create(context.Background(), &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - }, - }) - require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { - logger.Log(t, "deleting gateway namesapce") - k8sClient.Delete(context.Background(), &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - }, - }) - }) - - defaultInstances := pointer.Int32(2) - maxInstances := pointer.Int32(8) - minInstances := pointer.Int32(1) - // create a GatewayClassConfig with configuration set + // Create a GatewayClassConfig. gatewayClassConfigName := "gateway-class-config" gatewayClassConfig := &v1alpha1.GatewayClassConfig{ ObjectMeta: metav1.ObjectMeta{ @@ -99,8 +91,7 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { Name: gatewayClassConfigName, } - // create gateway class referencing gateway-class-config - gatewayClassName := "gateway-class" + // Create gateway class referencing gateway-class-config. logger.Log(t, "creating controlled gateway class") createGatewayClass(t, k8sClient, gatewayClassName, gatewayClassControllerName, gatewayParametersRef) helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { @@ -108,7 +99,7 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.GatewayClass{}) }) - // Create a certificate to reference in listeners + // Create a certificate to reference in listeners. certificateInfo := generateCertificate(t, nil, "certificate.consul.local") certificateName := "certificate" certificate := &corev1.Secret{ @@ -132,24 +123,24 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { k8sClient.Delete(context.Background(), certificate) }) - // Create gateway referencing gateway class config - gatewayName := "gateway" + // Create gateway referencing gateway class. + gatewayName := "gcctestgateway" + namespace logger.Log(t, "creating controlled gateway") gateway := createGateway(t, k8sClient, gatewayName, namespace, gatewayClassName, certificateName) - // make sure it exists - logger.Log(t, "checking that gateway one is synchronized to Consul") - checkConsulExists(t, consulClient, api.APIGateway, gatewayName) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { logger.Log(t, "deleting all gateways") k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.Gateway{}, client.InNamespace(namespace)) }) + // Ensure it exists. + logger.Log(t, "checking that gateway is synchronized to Consul") + checkConsulExists(t, consulClient, api.APIGateway, gatewayName) + // Scenario: Gateway deployment should match the default instances defined on the gateway class config logger.Log(t, "checking that gateway instances match defined gateway class config") checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, defaultInstances, gateway) - //Scenario: Updating the GatewayClassConfig should not affect gateways that have already been created + // Scenario: Updating the GatewayClassConfig should not affect gateways that have already been created logger.Log(t, "updating gatewayclassconfig values") err = k8sClient.Get(context.Background(), types.NamespacedName{Name: gatewayClassConfigName, Namespace: namespace}, gatewayClassConfig) require.NoError(t, err) @@ -159,10 +150,8 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { require.NoError(t, err) checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, defaultInstances, gateway) - //Scenario: gateways should be able to scale independently and not get overridden by the controller unless it's above the max - scale(t, k8sClient, gateway.Name, gateway.Namespace, maxInstances) - checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, maxInstances, gateway) - scale(t, k8sClient, gateway.Name, gateway.Namespace, pointer.Int32(10)) + // Scenario: gateways should be able to scale independently and not get overridden by the controller unless it's above the max + scale(t, k8sClient, gateway.Name, gateway.Namespace, pointer.Int32(*maxInstances+1)) checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, maxInstances, gateway) scale(t, k8sClient, gateway.Name, gateway.Namespace, pointer.Int32(0)) checkNumberOfInstances(t, k8sClient, consulClient, gateway.Name, gateway.Namespace, minInstances, gateway) @@ -172,36 +161,52 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { func scale(t *testing.T, client client.Client, name, namespace string, scaleTo *int32) { t.Helper() - retryCheck(t, 30, func(r *retry.R) { - var deployment appsv1.Deployment - err := client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, &deployment) - require.NoError(r, err) + var deployment appsv1.Deployment + err := client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, &deployment) + require.NoError(t, err) + + logger.Log(t, fmt.Sprintf("scaling gateway from %d to %d", *deployment.Spec.Replicas, *scaleTo)) + + deployment.Spec.Replicas = scaleTo + err = client.Update(context.Background(), &deployment) + require.NoError(t, err) - deployment.Spec.Replicas = scaleTo - err = client.Update(context.Background(), &deployment) - require.NoError(r, err) - }) } func checkNumberOfInstances(t *testing.T, k8client client.Client, consulClient *api.Client, name, namespace string, wantNumber *int32, gateway *gwv1beta1.Gateway) { t.Helper() - retryCheck(t, 30, func(r *retry.R) { - //first check to make sure the number of replicas has been set properly + retryCheckWithWait(t, 30, 10*time.Second, func(r *retry.R) { + logger.Log(t, "checking that gateway instances match defined gateway class config") + logger.Log(t, fmt.Sprintf("want: %d", *wantNumber)) + + // Ensure the number of replicas has been set properly. var deployment appsv1.Deployment err := k8client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, &deployment) require.NoError(r, err) - require.EqualValues(r, *wantNumber, *deployment.Spec.Replicas) + logger.Log(t, fmt.Sprintf("deployment replicas: %d", *deployment.Spec.Replicas)) + require.EqualValues(r, *wantNumber, *deployment.Spec.Replicas, "deployment replicas should match the number of instances defined on the gateway class config") - //then check to make sure the number of gateway pods matches the replicas generated + // Ensure the number of gateway pods matches the replicas generated. podList := corev1.PodList{} labels := common.LabelsForGateway(gateway) err = k8client.List(context.Background(), &podList, client.InNamespace(namespace), client.MatchingLabels(labels)) require.NoError(r, err) - require.EqualValues(r, *wantNumber, len(podList.Items)) + logger.Log(t, fmt.Sprintf("number of pods: %d", len(podList.Items))) + require.EqualValues(r, *wantNumber, len(podList.Items), "number of pods should match the number of instances defined on the gateway class config") + // Ensure the number of services matches the replicas generated. services, _, err := consulClient.Catalog().Service(name, "", nil) + seenServices := map[string]interface{}{} require.NoError(r, err) - require.EqualValues(r, *wantNumber, len(services)) + logger.Log(t, fmt.Sprintf("number of services: %d", len(services))) + //we need to double check that we aren't double counting services with the same ID + for _, s := range services { + seenServices[s.ServiceID] = true + logger.Log(t, fmt.Sprintf("service info: id: %s, name: %s, namespace: %s", s.ServiceID, s.ServiceName, s.Namespace)) + } + + logger.Log(t, fmt.Sprintf("number of services: %d", len(services))) + require.EqualValues(r, int(*wantNumber), len(seenServices), "number of services should match the number of instances defined on the gateway class config") }) } diff --git a/acceptance/tests/api-gateway/api_gateway_tenancy_test.go b/acceptance/tests/api-gateway/api_gateway_tenancy_test.go index e7748b9226..716f09bdba 100644 --- a/acceptance/tests/api-gateway/api_gateway_tenancy_test.go +++ b/acceptance/tests/api-gateway/api_gateway_tenancy_test.go @@ -347,9 +347,13 @@ func generateCertificate(t *testing.T, ca *certificateInfo, commonName string) * } func retryCheck(t *testing.T, count int, fn func(r *retry.R)) { + retryCheckWithWait(t, count, 2*time.Second, fn) +} + +func retryCheckWithWait(t *testing.T, count int, wait time.Duration, fn func(r *retry.R)) { t.Helper() - counter := &retry.Counter{Count: count, Wait: 2 * time.Second} + counter := &retry.Counter{Count: count, Wait: wait} retry.RunWith(counter, t, fn) } From 95af4c7b135fae46f7818a49ae7e927649d0b094 Mon Sep 17 00:00:00 2001 From: aahel Date: Tue, 27 Jun 2023 07:58:18 +0530 Subject: [PATCH 043/120] always update acl policy if it exists (#2392) * always update acl policy if it exists * added changelog * added unit test * fix typo * added some additional assertions to test * refactored create_or_update unit test --- .changelog/2392.txt | 3 + .../server-acl-init/create_or_update.go | 57 +++++++--------- .../server-acl-init/create_or_update_test.go | 68 +++++++++++++++++++ 3 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 .changelog/2392.txt diff --git a/.changelog/2392.txt b/.changelog/2392.txt new file mode 100644 index 0000000000..e15ef152b1 --- /dev/null +++ b/.changelog/2392.txt @@ -0,0 +1,3 @@ +```release-note:bug +control-plane: Always update ACL policies upon upgrade +``` \ No newline at end of file diff --git a/control-plane/subcommand/server-acl-init/create_or_update.go b/control-plane/subcommand/server-acl-init/create_or_update.go index d14fbc845c..50f215eacb 100644 --- a/control-plane/subcommand/server-acl-init/create_or_update.go +++ b/control-plane/subcommand/server-acl-init/create_or_update.go @@ -315,42 +315,37 @@ func (c *Command) createOrUpdateACLPolicy(policy api.ACLPolicy, consulClient *ap // Allowing the Consul node name to be configurable also requires any sync // policy to be updated in case the node name has changed. if isPolicyExistsErr(err, policy.Name) { - if c.flagEnableNamespaces || c.flagSyncCatalog { - c.log.Info(fmt.Sprintf("Policy %q already exists, updating", policy.Name)) + c.log.Info(fmt.Sprintf("Policy %q already exists, updating", policy.Name)) - // The policy ID is required in any PolicyUpdate call, so first we need to - // get the existing policy to extract its ID. - existingPolicies, _, err := consulClient.ACL().PolicyList(&api.QueryOptions{}) - if err != nil { - return err - } - - // Find the policy that matches our name and description - // and that's the ID we need - for _, existingPolicy := range existingPolicies { - if existingPolicy.Name == policy.Name && existingPolicy.Description == policy.Description { - policy.ID = existingPolicy.ID - } - } + // The policy ID is required in any PolicyUpdate call, so first we need to + // get the existing policy to extract its ID. + existingPolicies, _, err := consulClient.ACL().PolicyList(&api.QueryOptions{}) + if err != nil { + return err + } - // This shouldn't happen, because we're looking for a policy - // only after we've hit a `Policy already exists` error. - // The only time it might happen is if a user has manually created a policy - // with this name but used a different description. In this case, - // we don't want to overwrite the policy so we just error. - if policy.ID == "" { - return fmt.Errorf("policy found with name %q but not with expected description %q; "+ - "if this policy was created manually it must be renamed to something else because this name is reserved by consul-k8s", - policy.Name, policy.Description) + // Find the policy that matches our name and description + // and that's the ID we need + for _, existingPolicy := range existingPolicies { + if existingPolicy.Name == policy.Name && existingPolicy.Description == policy.Description { + policy.ID = existingPolicy.ID } + } - // Update the policy now that we've found its ID - _, _, err = consulClient.ACL().PolicyUpdate(&policy, &api.WriteOptions{}) - return err - } else { - c.log.Info(fmt.Sprintf("Policy %q already exists, skipping update", policy.Name)) - return nil + // This shouldn't happen, because we're looking for a policy + // only after we've hit a `Policy already exists` error. + // The only time it might happen is if a user has manually created a policy + // with this name but used a different description. In this case, + // we don't want to overwrite the policy so we just error. + if policy.ID == "" { + return fmt.Errorf("policy found with name %q but not with expected description %q; "+ + "if this policy was created manually it must be renamed to something else because this name is reserved by consul-k8s", + policy.Name, policy.Description) } + + // Update the policy now that we've found its ID + _, _, err = consulClient.ACL().PolicyUpdate(&policy, &api.WriteOptions{}) + return err } return err } diff --git a/control-plane/subcommand/server-acl-init/create_or_update_test.go b/control-plane/subcommand/server-acl-init/create_or_update_test.go index 6aff677dda..84ccdc1635 100644 --- a/control-plane/subcommand/server-acl-init/create_or_update_test.go +++ b/control-plane/subcommand/server-acl-init/create_or_update_test.go @@ -70,3 +70,71 @@ func TestCreateOrUpdateACLPolicy_ErrorsIfDescriptionDoesNotMatch(t *testing.T) { require.NoError(err) require.Equal(policyDescription, rereadPolicy.Description) } + +func TestCreateOrUpdateACLPolicy(t *testing.T) { + require := require.New(t) + ui := cli.NewMockUi() + k8s := fake.NewSimpleClientset() + cmd := Command{ + UI: ui, + clientset: k8s, + log: hclog.NewNullLogger(), + } + cmd.init() + // Start Consul. + bootToken := "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" + svr, err := testutil.NewTestServerConfigT(t, func(c *testutil.TestServerConfig) { + c.ACL.Enabled = true + c.ACL.Tokens.InitialManagement = bootToken + }) + require.NoError(err) + defer svr.Stop() + svr.WaitForLeader(t) + + // Get a Consul client. + consul, err := api.NewClient(&api.Config{ + Address: svr.HTTPAddr, + Token: bootToken, + }) + require.NoError(err) + connectInjectRule, err := cmd.injectRules() + require.NoError(err) + aclReplRule, err := cmd.aclReplicationRules() + require.NoError(err) + policyDescription := "policy-description" + policyName := "policy-name" + cases := []struct { + Name string + PolicyDescription string + PolicyName string + Rules string + }{ + { + Name: "create", + PolicyDescription: policyDescription, + PolicyName: policyName, + Rules: connectInjectRule, + }, + { + Name: "update", + PolicyDescription: policyDescription, + PolicyName: policyName, + Rules: aclReplRule, + }, + } + for _, tt := range cases { + t.Run(tt.Name, func(t *testing.T) { + err = cmd.createOrUpdateACLPolicy(api.ACLPolicy{ + Name: tt.PolicyName, + Description: tt.PolicyDescription, + Rules: tt.Rules, + }, consul) + require.Nil(err) + policy, _, err := consul.ACL().PolicyReadByName(tt.PolicyName, nil) + require.Nil(err) + require.Equal(tt.Rules, policy.Rules) + require.Equal(tt.PolicyName, policy.Name) + require.Equal(tt.PolicyDescription, policy.Description) + }) + } +} From e17684617a0f2b8894082513f78a135f3ab0b832 Mon Sep 17 00:00:00 2001 From: Mike Morris Date: Tue, 27 Jun 2023 13:55:10 -0400 Subject: [PATCH 044/120] Proxy Lifecycle helm, connect-inject and acceptance tests (#2233) Proxy Lifecycle helm, connect-inject and acceptance tests (#2233) Co-authored-by: Nitya Dhanushkodi --- .changelog/2233.txt | 3 + acceptance/framework/config/config.go | 15 +- .../framework/connhelper/connect_helper.go | 12 +- acceptance/framework/flags/flags.go | 39 +- .../connect/connect_proxy_lifecycle_test.go | 214 +++++++++++ .../templates/connect-inject-deployment.yaml | 13 + .../test/unit/connect-inject-deployment.bats | 155 +++++++- charts/consul/values.yaml | 26 +- cli/helm/values.go | 11 +- control-plane/connect-inject/common/common.go | 34 ++ .../connect-inject/common/common_test.go | 166 +++++++++ .../constants/annotations_and_labels.go | 7 + .../connect-inject/constants/constants.go | 6 + .../lifecycle/lifecycle_configuration.go | 95 +++++ .../lifecycle/lifecycle_configuration_test.go | 351 ++++++++++++++++++ .../metrics/metrics_configuration.go | 42 +-- .../metrics/metrics_configuration_test.go | 143 ------- .../webhook/consul_dataplane_sidecar.go | 39 ++ .../webhook/consul_dataplane_sidecar_test.go | 191 +++++++++- .../connect-inject/webhook/mesh_webhook.go | 8 + .../subcommand/inject-connect/command.go | 25 ++ 21 files changed, 1353 insertions(+), 242 deletions(-) create mode 100644 .changelog/2233.txt create mode 100644 acceptance/tests/connect/connect_proxy_lifecycle_test.go create mode 100644 control-plane/connect-inject/lifecycle/lifecycle_configuration.go create mode 100644 control-plane/connect-inject/lifecycle/lifecycle_configuration_test.go diff --git a/.changelog/2233.txt b/.changelog/2233.txt new file mode 100644 index 0000000000..bb929501c9 --- /dev/null +++ b/.changelog/2233.txt @@ -0,0 +1,3 @@ +```release-note:feature +Add support for configuring graceful shutdown proxy lifecycle management settings. +``` diff --git a/acceptance/framework/config/config.go b/acceptance/framework/config/config.go index 18673ca260..7151a75908 100644 --- a/acceptance/framework/config/config.go +++ b/acceptance/framework/config/config.go @@ -46,12 +46,14 @@ type TestConfig struct { DisablePeering bool - HelmChartVersion string - ConsulImage string - ConsulK8SImage string - ConsulVersion *version.Version - EnvoyImage string - ConsulCollectorImage string + HelmChartVersion string + ConsulImage string + ConsulK8SImage string + ConsulDataplaneImage string + ConsulVersion *version.Version + ConsulDataplaneVersion *version.Version + EnvoyImage string + ConsulCollectorImage string HCPResourceID string @@ -110,6 +112,7 @@ func (t *TestConfig) HelmValuesFromConfig() (map[string]string, error) { setIfNotEmpty(helmValues, "global.image", t.ConsulImage) setIfNotEmpty(helmValues, "global.imageK8S", t.ConsulK8SImage) setIfNotEmpty(helmValues, "global.imageEnvoy", t.EnvoyImage) + setIfNotEmpty(helmValues, "global.imageConsulDataplane", t.ConsulDataplaneImage) return helmValues, nil } diff --git a/acceptance/framework/connhelper/connect_helper.go b/acceptance/framework/connhelper/connect_helper.go index 8a7f4d3d53..8695e74d56 100644 --- a/acceptance/framework/connhelper/connect_helper.go +++ b/acceptance/framework/connhelper/connect_helper.go @@ -50,8 +50,8 @@ type ConnectHelper struct { // consulCluster is the cluster to use for the test. consulCluster consul.Cluster - // consulClient is the client used to test service mesh connectivity. - consulClient *api.Client + // ConsulClient is the client used to test service mesh connectivity. + ConsulClient *api.Client } // Setup creates a new cluster using the New*Cluster function and assigns it @@ -69,14 +69,14 @@ func (c *ConnectHelper) Setup(t *testing.T) { func (c *ConnectHelper) Install(t *testing.T) { logger.Log(t, "Installing Consul cluster") c.consulCluster.Create(t) - c.consulClient, _ = c.consulCluster.SetupConsulClient(t, c.Secure) + c.ConsulClient, _ = c.consulCluster.SetupConsulClient(t, c.Secure) } // Upgrade uses the existing Consul cluster and upgrades it using Helm values // set by the Secure, AutoEncrypt, and HelmValues fields. func (c *ConnectHelper) Upgrade(t *testing.T) { require.NotNil(t, c.consulCluster, "consulCluster must be set before calling Upgrade (Call Install first).") - require.NotNil(t, c.consulClient, "consulClient must be set before calling Upgrade (Call Install first).") + require.NotNil(t, c.ConsulClient, "ConsulClient must be set before calling Upgrade (Call Install first).") logger.Log(t, "upgrading Consul cluster") c.consulCluster.Upgrade(t, c.helmValues()) @@ -96,7 +96,7 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { t.Cleanup(func() { retrier := &retry.Timer{Timeout: 30 * time.Second, Wait: 100 * time.Millisecond} retry.RunWith(retrier, t, func(r *retry.R) { - tokens, _, err := c.consulClient.ACL().TokenList(nil) + tokens, _, err := c.ConsulClient.ACL().TokenList(nil) require.NoError(r, err) for _, token := range tokens { require.NotContains(r, token.Description, StaticServerName) @@ -142,7 +142,7 @@ func (c *ConnectHelper) TestConnectionFailureWithoutIntention(t *testing.T) { // the static-client pod. func (c *ConnectHelper) CreateIntention(t *testing.T) { logger.Log(t, "creating intention") - _, _, err := c.consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ + _, _, err := c.ConsulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ Kind: api.ServiceIntentions, Name: StaticServerName, Sources: []*api.SourceIntention{ diff --git a/acceptance/framework/flags/flags.go b/acceptance/framework/flags/flags.go index fd1831c5e6..5df09f853a 100644 --- a/acceptance/framework/flags/flags.go +++ b/acceptance/framework/flags/flags.go @@ -34,14 +34,16 @@ type TestFlags struct { flagEnableTransparentProxy bool - flagHelmChartVersion string - flagConsulImage string - flagConsulK8sImage string - flagConsulVersion string - flagEnvoyImage string - flagConsulCollectorImage string - flagVaultHelmChartVersion string - flagVaultServerVersion string + flagHelmChartVersion string + flagConsulImage string + flagConsulK8sImage string + flagConsulDataplaneImage string + flagConsulVersion string + flagConsulDataplaneVersion string + flagEnvoyImage string + flagConsulCollectorImage string + flagVaultHelmChartVersion string + flagVaultServerVersion string flagHCPResourceID string @@ -75,7 +77,9 @@ func (t *TestFlags) init() { flag.StringVar(&t.flagConsulImage, "consul-image", "", "The Consul image to use for all tests.") flag.StringVar(&t.flagConsulK8sImage, "consul-k8s-image", "", "The consul-k8s image to use for all tests.") + flag.StringVar(&t.flagConsulDataplaneImage, "consul-dataplane-image", "", "The consul-dataplane image to use for all tests.") flag.StringVar(&t.flagConsulVersion, "consul-version", "", "The consul version used for all tests.") + flag.StringVar(&t.flagConsulDataplaneVersion, "consul-dataplane-version", "", "The consul-dataplane version used for all tests.") flag.StringVar(&t.flagHelmChartVersion, "helm-chart-version", config.HelmChartPath, "The helm chart used for all tests.") flag.StringVar(&t.flagEnvoyImage, "envoy-image", "", "The Envoy image to use for all tests.") flag.StringVar(&t.flagConsulCollectorImage, "consul-collector-image", "", "The consul collector image to use for all tests.") @@ -155,6 +159,7 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { // if the Version is empty consulVersion will be nil consulVersion, _ := version.NewVersion(t.flagConsulVersion) + consulDataplaneVersion, _ := version.NewVersion(t.flagConsulDataplaneVersion) //vaultserverVersion, _ := version.NewVersion(t.flagVaultServerVersion) return &config.TestConfig{ @@ -180,14 +185,16 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { DisablePeering: t.flagDisablePeering, - HelmChartVersion: t.flagHelmChartVersion, - ConsulImage: t.flagConsulImage, - ConsulK8SImage: t.flagConsulK8sImage, - ConsulVersion: consulVersion, - EnvoyImage: t.flagEnvoyImage, - ConsulCollectorImage: t.flagConsulCollectorImage, - VaultHelmChartVersion: t.flagVaultHelmChartVersion, - VaultServerVersion: t.flagVaultServerVersion, + HelmChartVersion: t.flagHelmChartVersion, + ConsulImage: t.flagConsulImage, + ConsulK8SImage: t.flagConsulK8sImage, + ConsulDataplaneImage: t.flagConsulDataplaneImage, + ConsulVersion: consulVersion, + ConsulDataplaneVersion: consulDataplaneVersion, + EnvoyImage: t.flagEnvoyImage, + ConsulCollectorImage: t.flagConsulCollectorImage, + VaultHelmChartVersion: t.flagVaultHelmChartVersion, + VaultServerVersion: t.flagVaultServerVersion, HCPResourceID: t.flagHCPResourceID, diff --git a/acceptance/tests/connect/connect_proxy_lifecycle_test.go b/acceptance/tests/connect/connect_proxy_lifecycle_test.go new file mode 100644 index 0000000000..ecdc51b547 --- /dev/null +++ b/acceptance/tests/connect/connect_proxy_lifecycle_test.go @@ -0,0 +1,214 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package connect + +import ( + "context" + "fmt" + "strconv" + "strings" + "testing" + "time" + + "github.com/hashicorp/consul-k8s/acceptance/framework/connhelper" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/hashicorp/go-version" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type LifecycleShutdownConfig struct { + secure bool + helmValues map[string]string +} + +const ( + helmDrainListenersKey = "connectInject.sidecarProxy.lifecycle.defaultEnableShutdownDrainListeners" + helmGracePeriodSecondsKey = "connectInject.sidecarProxy.lifecycle.defaultShutdownGracePeriodSeconds" +) + +// Test the endpoints controller cleans up force-killed pods. +func TestConnectInject_ProxyLifecycleShutdown(t *testing.T) { + cfg := suite.Config() + + ver, err := version.NewVersion("1.2.0") + require.NoError(t, err) + if cfg.ConsulDataplaneVersion != nil && cfg.ConsulDataplaneVersion.LessThan(ver) { + t.Skipf("skipping this test because proxy lifecycle management is not supported in consul-dataplane version %v", cfg.ConsulDataplaneVersion.String()) + } + + for _, testCfg := range []LifecycleShutdownConfig{ + {secure: false, helmValues: map[string]string{}}, + {secure: true, helmValues: map[string]string{}}, + {secure: false, helmValues: map[string]string{ + helmDrainListenersKey: "true", + helmGracePeriodSecondsKey: "15", + }}, + {secure: true, helmValues: map[string]string{ + helmDrainListenersKey: "true", + helmGracePeriodSecondsKey: "15", + }}, + {secure: false, helmValues: map[string]string{ + helmDrainListenersKey: "false", + helmGracePeriodSecondsKey: "15", + }}, + {secure: true, helmValues: map[string]string{ + helmDrainListenersKey: "false", + helmGracePeriodSecondsKey: "15", + }}, + {secure: false, helmValues: map[string]string{ + helmDrainListenersKey: "false", + helmGracePeriodSecondsKey: "0", + }}, + {secure: true, helmValues: map[string]string{ + helmDrainListenersKey: "false", + helmGracePeriodSecondsKey: "0", + }}, + } { + // Determine if listeners should be expected to drain inbound connections + var drainListenersEnabled bool + val, ok := testCfg.helmValues[helmDrainListenersKey] + if ok { + drainListenersEnabled, err = strconv.ParseBool(val) + require.NoError(t, err) + } + + // Determine expected shutdown grace period + var gracePeriodSeconds int64 + val, ok = testCfg.helmValues[helmGracePeriodSecondsKey] + if ok { + gracePeriodSeconds, err = strconv.ParseInt(val, 10, 64) + require.NoError(t, err) + } else { + // Half of the helm default to speed tests up + gracePeriodSeconds = 15 + } + + name := fmt.Sprintf("secure: %t, drainListeners: %t, gracePeriodSeconds: %d", testCfg.secure, drainListenersEnabled, gracePeriodSeconds) + t.Run(name, func(t *testing.T) { + ctx := suite.Environment().DefaultContext(t) + releaseName := helpers.RandomName() + + connHelper := connhelper.ConnectHelper{ + ClusterKind: consul.Helm, + Secure: testCfg.secure, + ReleaseName: releaseName, + Ctx: ctx, + Cfg: cfg, + HelmValues: testCfg.helmValues, + } + + connHelper.Setup(t) + connHelper.Install(t) + connHelper.DeployClientAndServer(t) + + // TODO: should this move into connhelper.DeployClientAndServer? + logger.Log(t, "waiting for static-client and static-server to be registered with Consul") + retry.Run(t, func(r *retry.R) { + for _, name := range []string{ + "static-client", + "static-client-sidecar-proxy", + "static-server", + "static-server-sidecar-proxy", + } { + logger.Logf(t, "checking for %s service in Consul catalog", name) + instances, _, err := connHelper.ConsulClient.Catalog().Service(name, "", nil) + r.Check(err) + + if len(instances) != 1 { + r.Errorf("expected 1 instance of %s", name) + } + } + }) + + if testCfg.secure { + connHelper.TestConnectionFailureWithoutIntention(t) + connHelper.CreateIntention(t) + } + + connHelper.TestConnectionSuccess(t) + + // Get static-client pod name + ns := ctx.KubectlOptions(t).Namespace + pods, err := ctx.KubernetesClient(t).CoreV1().Pods(ns).List( + context.Background(), + metav1.ListOptions{ + LabelSelector: "app=static-client", + }, + ) + require.NoError(t, err) + require.Len(t, pods.Items, 1) + clientPodName := pods.Items[0].Name + + var terminationGracePeriod int64 = 60 + logger.Logf(t, "killing the %q pod with %dseconds termination grace period", clientPodName, terminationGracePeriod) + err = ctx.KubernetesClient(t).CoreV1().Pods(ns).Delete(context.Background(), clientPodName, metav1.DeleteOptions{GracePeriodSeconds: &terminationGracePeriod}) + require.NoError(t, err) + + // Exec into terminating pod, not just any static-client pod + args := []string{"exec", clientPodName, "-c", connhelper.StaticClientName, "--", "curl", "-vvvsSf"} + + if cfg.EnableTransparentProxy { + args = append(args, "http://static-server") + } else { + args = append(args, "http://localhost:1234") + } + + if gracePeriodSeconds > 0 { + // Ensure outbound requests are still successful during grace + // period. + retry.RunWith(&retry.Timer{Timeout: time.Duration(gracePeriodSeconds) * time.Second, Wait: 2 * time.Second}, t, func(r *retry.R) { + output, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), args...) + require.NoError(r, err) + require.Condition(r, func() bool { + exists := false + if strings.Contains(output, "curl: (7) Failed to connect") { + exists = true + } + return !exists + }) + }) + + // If listener draining is enabled, ensure inbound + // requests are rejected during grace period. + // connHelper.TestConnectionSuccess(t) + } else { + // Ensure outbound requests fail because proxy has terminated + retry.RunWith(&retry.Timer{Timeout: time.Duration(terminationGracePeriod) * time.Second, Wait: 2 * time.Second}, t, func(r *retry.R) { + output, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), args...) + require.Error(r, err) + require.Condition(r, func() bool { + exists := false + if strings.Contains(output, "curl: (7) Failed to connect") { + exists = true + } + return exists + }) + }) + } + + logger.Log(t, "ensuring pod is deregistered after termination") + retry.Run(t, func(r *retry.R) { + for _, name := range []string{ + "static-client", + "static-client-sidecar-proxy", + } { + logger.Logf(t, "checking for %s service in Consul catalog", name) + instances, _, err := connHelper.ConsulClient.Catalog().Service(name, "", nil) + r.Check(err) + + for _, instance := range instances { + if strings.Contains(instance.ServiceID, clientPodName) { + r.Errorf("%s is still registered", instance.ServiceID) + } + } + } + }) + }) + } +} diff --git a/charts/consul/templates/connect-inject-deployment.yaml b/charts/consul/templates/connect-inject-deployment.yaml index 479e05b25a..14c3961b4e 100644 --- a/charts/consul/templates/connect-inject-deployment.yaml +++ b/charts/consul/templates/connect-inject-deployment.yaml @@ -234,6 +234,19 @@ spec: -default-sidecar-proxy-cpu-request={{ $resources.requests.cpu }} \ {{- end }} -default-envoy-proxy-concurrency={{ .Values.connectInject.sidecarProxy.concurrency }} \ + {{- if .Values.connectInject.sidecarProxy.lifecycle.defaultEnabled }} + -default-enable-sidecar-proxy-lifecycle=true \ + {{- else }} + -default-enable-sidecar-proxy-lifecycle=false \ + {{- end }} + {{- if .Values.connectInject.sidecarProxy.lifecycle.defaultEnableShutdownDrainListeners }} + -default-enable-sidecar-proxy-lifecycle-shutdown-drain-listeners=true \ + {{- else }} + -default-enable-sidecar-proxy-lifecycle-shutdown-drain-listeners=false \ + {{- end }} + -default-sidecar-proxy-lifecycle-shutdown-grace-period-seconds={{ .Values.connectInject.sidecarProxy.lifecycle.defaultShutdownGracePeriodSeconds }} \ + -default-sidecar-proxy-lifecycle-graceful-port={{ .Values.connectInject.sidecarProxy.lifecycle.defaultGracefulPort }} \ + -default-sidecar-proxy-lifecycle-graceful-shutdown-path="{{ .Values.connectInject.sidecarProxy.lifecycle.defaultGracefulShutdownPath }}" \ {{- if .Values.connectInject.initContainer }} {{- $initResources := .Values.connectInject.initContainer.resources }} diff --git a/charts/consul/test/unit/connect-inject-deployment.bats b/charts/consul/test/unit/connect-inject-deployment.bats index c1bc63ffc3..ccc6eca68c 100755 --- a/charts/consul/test/unit/connect-inject-deployment.bats +++ b/charts/consul/test/unit/connect-inject-deployment.bats @@ -999,7 +999,7 @@ load _helpers local actual=$(echo "$cmd" | yq 'any(contains("-init-container-memory-limit=150Mi"))' | tee /dev/stderr) [ "${actual}" = "true" ] - + } @test "connectInject/Deployment: can set init container resources" { @@ -1231,6 +1231,144 @@ load _helpers [ "${actual}" = "true" ] } +#-------------------------------------------------------------------- +# sidecarProxy.lifecycle + +@test "connectInject/Deployment: by default sidecar proxy lifecycle management is enabled" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-enable-sidecar-proxy-lifecycle"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: sidecar proxy lifecycle management can be disabled" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.sidecarProxy.lifecycle.defaultEnabled=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-enable-sidecar-proxy-lifecycle=false"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: by default sidecar proxy lifecycle management shutdown listener draining is enabled" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-enable-sidecar-proxy-lifecycle-shutdown-drain-listeners"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: sidecar proxy lifecycle management shutdown listener draining can be disabled" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.sidecarProxy.lifecycle.defaultEnableShutdownDrainListeners=false' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-enable-sidecar-proxy-lifecycle-shutdown-drain-listeners=false"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: by default sidecar proxy lifecycle management shutdown grace period is set to 30 seconds" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-lifecycle-shutdown-grace-period-seconds=30"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: sidecar proxy lifecycle management shutdown grace period can be set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.sidecarProxy.lifecycle.defaultShutdownGracePeriodSeconds=23' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-lifecycle-shutdown-grace-period-seconds=23"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: by default sidecar proxy lifecycle management port is set to 20600" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-lifecycle-graceful-port=20600"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: sidecar proxy lifecycle management port can be set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.sidecarProxy.lifecycle.defaultGracefulPort=20307' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-lifecycle-graceful-port=20307"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: by default sidecar proxy lifecycle management graceful shutdown path is set to /graceful_shutdown" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-lifecycle-graceful-shutdown-path=\"/graceful_shutdown\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "connectInject/Deployment: sidecar proxy lifecycle management graceful shutdown path can be set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/connect-inject-deployment.yaml \ + --set 'connectInject.enabled=true' \ + --set 'connectInject.sidecarProxy.lifecycle.defaultGracefulShutdownPath=/exit' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-default-sidecar-proxy-lifecycle-graceful-shutdown-path=\"/exit\""))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # priorityClassName @@ -1418,7 +1556,7 @@ load _helpers } #-------------------------------------------------------------------- -# cni +# cni @test "connectInject/Deployment: cni is disabled by default" { cd `chart_dir` @@ -2300,7 +2438,7 @@ reservedNameTest() { --set 'global.cloud.authUrl.secretName=auth-url-name' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.authUrl.secretName or global.cloud.authUrl.secretKey is defined, both must be set." ]] } @@ -2321,7 +2459,7 @@ reservedNameTest() { --set 'global.cloud.authUrl.secretKey=auth-url-key' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.authUrl.secretName or global.cloud.authUrl.secretKey is defined, both must be set." ]] } @@ -2342,7 +2480,7 @@ reservedNameTest() { --set 'global.cloud.apiHost.secretName=auth-url-name' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.apiHost.secretName or global.cloud.apiHost.secretKey is defined, both must be set." ]] } @@ -2363,7 +2501,7 @@ reservedNameTest() { --set 'global.cloud.apiHost.secretKey=auth-url-key' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.apiHost.secretName or global.cloud.apiHost.secretKey is defined, both must be set." ]] } @@ -2384,7 +2522,7 @@ reservedNameTest() { --set 'global.cloud.scadaAddress.secretName=scada-address-name' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.scadaAddress.secretName or global.cloud.scadaAddress.secretKey is defined, both must be set." ]] } @@ -2405,7 +2543,7 @@ reservedNameTest() { --set 'global.cloud.scadaAddress.secretKey=scada-address-key' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.scadaAddress.secretName or global.cloud.scadaAddress.secretKey is defined, both must be set." ]] } @@ -2449,4 +2587,3 @@ reservedNameTest() { jq -r '. | select( .name == "CONSUL_TLS_SERVER_NAME").value' | tee /dev/stderr) [ "${actual}" = "server.dc1.consul" ] } - diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 89336e319e..ad1f829399 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -584,7 +584,7 @@ global: # The name (and tag) of the consul-dataplane Docker image used for the # connect-injected sidecar proxies and mesh, terminating, and ingress gateways. # @default: hashicorp/consul-dataplane: - imageConsulDataplane: "docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.2-dev" + imageConsulDataplane: "docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.3-dev" # Configuration for running this Helm chart on the Red Hat OpenShift platform. # This Helm chart currently supports OpenShift v4.x+. @@ -2108,7 +2108,7 @@ connectInject: # @type: string nodeSelector: null - # Toleration settings for gateway pods created with the managed gateway class. + # Toleration settings for gateway pods created with the managed gateway class. # This should be a multi-line string matching the # [Tolerations](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/) array in a Pod spec. # @@ -2134,7 +2134,7 @@ connectInject: service: null # This value defines the number of pods to deploy for each Gateway as well as a min and max number of pods for all Gateways - deployment: + deployment: defaultInstances: 1 maxInstances: 1 minInstances: 1 @@ -2554,6 +2554,26 @@ connectInject: # Recommended production default: 100m # @type: string cpu: null + # Set default lifecycle management configuration for sidecar proxy. + # These settings can be overridden on a per-pod basis via these annotations: + # + # - `consul.hashicorp.com/enable-sidecar-proxy-lifecycle` + # - `consul.hashicorp.com/enable-sidecar-proxy-shutdown-drain-listeners` + # - `consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds` + # - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-port` + # - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-shutdown-path` + # @type: map + lifecycle: + # @type: boolean + defaultEnabled: true + # @type: boolean + defaultEnableShutdownDrainListeners: true + # @type: integer + defaultShutdownGracePeriodSeconds: 30 + # @type: integer + defaultGracefulPort: 20600 + # @type: string + defaultGracefulShutdownPath: "/graceful_shutdown" # The resource settings for the Connect injected init container. If null, the resources # won't be set for the initContainer. The defaults are optimized for developer instances of diff --git a/cli/helm/values.go b/cli/helm/values.go index e6951074b1..06671382d1 100644 --- a/cli/helm/values.go +++ b/cli/helm/values.go @@ -411,7 +411,7 @@ type TransparentProxy struct { } type Metrics struct { - DefaultEnabled string `yaml:"defaultEnabled"` + DefaultEnabled bool `yaml:"defaultEnabled"` DefaultEnableMerging bool `yaml:"defaultEnableMerging"` DefaultMergedMetricsPort int `yaml:"defaultMergedMetricsPort"` DefaultPrometheusScrapePort int `yaml:"defaultPrometheusScrapePort"` @@ -425,12 +425,21 @@ type ACLInjectToken struct { type SidecarProxy struct { Resources Resources `yaml:"resources"` + Lifecycle Lifecycle `yaml:"lifecycle"` } type InitContainer struct { Resources Resources `yaml:"resources"` } +type Lifecycle struct { + DefaultEnabled bool `yaml:"defaultEnabled"` + DefaultEnableShutdownDrainListeners bool `yaml:"defaultEnableShutdownDrainListeners"` + DefaultShutdownGracePeriodSeconds int `yaml:"defaultShutdownGracePeriodSeconds"` + DefaultGracefulPort int `yaml:"defaultGracefulPort"` + DefaultGracefulShutdownPath string `yaml:"defaultGracefulShutdownPath"` +} + type ConnectInject struct { Enabled bool `yaml:"enabled"` Replicas int `yaml:"replicas"` diff --git a/control-plane/connect-inject/common/common.go b/control-plane/connect-inject/common/common.go index 67182e6d0a..a99d9fd12e 100644 --- a/control-plane/connect-inject/common/common.go +++ b/control-plane/connect-inject/common/common.go @@ -12,6 +12,40 @@ import ( corev1 "k8s.io/api/core/v1" ) +// DetermineAndValidatePort behaves as follows: +// If the annotation exists, validate the port and return it. +// If the annotation does not exist, return the default port. +// If the privileged flag is true, it will allow the port to be in the +// privileged port range of 1-1023. Otherwise, it will only allow ports in the +// unprivileged range of 1024-65535. +func DetermineAndValidatePort(pod corev1.Pod, annotation string, defaultPort string, privileged bool) (string, error) { + if raw, ok := pod.Annotations[annotation]; ok && raw != "" { + port, err := PortValue(pod, raw) + if err != nil { + return "", fmt.Errorf("%s annotation value of %s is not a valid integer", annotation, raw) + } + + if privileged && (port < 1 || port > 65535) { + return "", fmt.Errorf("%s annotation value of %d is not in the valid port range 1-65535", annotation, port) + } else if !privileged && (port < 1024 || port > 65535) { + return "", fmt.Errorf("%s annotation value of %d is not in the unprivileged port range 1024-65535", annotation, port) + } + + // If the annotation exists, return the validated port. + return fmt.Sprint(port), nil + } + + // If the annotation does not exist, return the default. + if defaultPort != "" { + port, err := PortValue(pod, defaultPort) + if err != nil { + return "", fmt.Errorf("%s is not a valid port on the pod %s", defaultPort, pod.Name) + } + return fmt.Sprint(port), nil + } + return "", nil +} + // PortValue returns the port of the container for the string value passed // in as an argument on the provided pod. func PortValue(pod corev1.Pod, value string) (int32, error) { diff --git a/control-plane/connect-inject/common/common_test.go b/control-plane/connect-inject/common/common_test.go index 3f995e2874..79a9294fe2 100644 --- a/control-plane/connect-inject/common/common_test.go +++ b/control-plane/connect-inject/common/common_test.go @@ -6,10 +6,153 @@ package common import ( "testing" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" + "github.com/hashicorp/consul-k8s/control-plane/namespaces" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +func TestCommonDetermineAndValidatePort(t *testing.T) { + cases := []struct { + Name string + Pod func(*corev1.Pod) *corev1.Pod + Annotation string + Privileged bool + DefaultPort string + Expected string + Err string + }{ + { + Name: "Valid annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "1234" + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: false, + Expected: "1234", + Err: "", + }, + { + Name: "Uses default when there's no annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: false, + DefaultPort: "4321", + Expected: "4321", + Err: "", + }, + { + Name: "Gets the value of the named default port when there's no annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Spec.Containers[0].Ports = []corev1.ContainerPort{ + { + Name: "web-port", + ContainerPort: 2222, + }, + } + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: false, + DefaultPort: "web-port", + Expected: "2222", + Err: "", + }, + { + Name: "Errors if the named default port doesn't exist on the pod", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: false, + DefaultPort: "web-port", + Expected: "", + Err: "web-port is not a valid port on the pod minimal", + }, + { + Name: "Gets the value of the named port", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "web-port" + pod.Spec.Containers[0].Ports = []corev1.ContainerPort{ + { + Name: "web-port", + ContainerPort: 2222, + }, + } + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: false, + DefaultPort: "4321", + Expected: "2222", + Err: "", + }, + { + Name: "Invalid annotation (not an integer)", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "not-an-int" + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: false, + Expected: "", + Err: "consul.hashicorp.com/test-annotation-port annotation value of not-an-int is not a valid integer", + }, + { + Name: "Invalid annotation (integer not in port range)", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "100000" + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: true, + Expected: "", + Err: "consul.hashicorp.com/test-annotation-port annotation value of 100000 is not in the valid port range 1-65535", + }, + { + Name: "Invalid annotation (integer not in unprivileged port range)", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "22" + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: false, + Expected: "", + Err: "consul.hashicorp.com/test-annotation-port annotation value of 22 is not in the unprivileged port range 1024-65535", + }, + { + Name: "Privileged ports allowed", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "22" + return pod + }, + Annotation: "consul.hashicorp.com/test-annotation-port", + Privileged: true, + Expected: "22", + Err: "", + }, + } + + for _, tt := range cases { + t.Run(tt.Name, func(t *testing.T) { + require := require.New(t) + + actual, err := DetermineAndValidatePort(*tt.Pod(minimal()), tt.Annotation, tt.DefaultPort, tt.Privileged) + + if tt.Err == "" { + require.NoError(err) + require.Equal(tt.Expected, actual) + } else { + require.EqualError(err, tt.Err) + } + }) + } +} + func TestPortValue(t *testing.T) { cases := []struct { Name string @@ -93,3 +236,26 @@ func TestPortValue(t *testing.T) { }) } } + +func minimal() *corev1.Pod { + return &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespaces.DefaultNamespace, + Name: "minimal", + Annotations: map[string]string{ + constants.AnnotationService: "foo", + }, + }, + + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "web", + }, + { + Name: "web-side", + }, + }, + }, + } +} diff --git a/control-plane/connect-inject/constants/annotations_and_labels.go b/control-plane/connect-inject/constants/annotations_and_labels.go index fa5c7da26c..4efcc24c74 100644 --- a/control-plane/connect-inject/constants/annotations_and_labels.go +++ b/control-plane/connect-inject/constants/annotations_and_labels.go @@ -100,6 +100,13 @@ const ( AnnotationSidecarProxyMemoryLimit = "consul.hashicorp.com/sidecar-proxy-memory-limit" AnnotationSidecarProxyMemoryRequest = "consul.hashicorp.com/sidecar-proxy-memory-request" + // annotations for sidecar proxy lifecycle configuration. + AnnotationEnableSidecarProxyLifecycle = "consul.hashicorp.com/enable-sidecar-proxy-lifecycle" + AnnotationEnableSidecarProxyLifecycleShutdownDrainListeners = "consul.hashicorp.com/enable-sidecar-proxy-lifecycle-shutdown-drain-listeners" + AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds = "consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds" + AnnotationSidecarProxyLifecycleGracefulPort = "consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-port" + AnnotationSidecarProxyLifecycleGracefulShutdownPath = "consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-shutdown-path" + // annotations for sidecar volumes. AnnotationConsulSidecarUserVolume = "consul.hashicorp.com/consul-sidecar-user-volume" AnnotationConsulSidecarUserVolumeMount = "consul.hashicorp.com/consul-sidecar-user-volume-mount" diff --git a/control-plane/connect-inject/constants/constants.go b/control-plane/connect-inject/constants/constants.go index 0a341cd577..ca6fe23606 100644 --- a/control-plane/connect-inject/constants/constants.go +++ b/control-plane/connect-inject/constants/constants.go @@ -27,4 +27,10 @@ const ( // MetaKeyPodName is the meta key name for Kubernetes pod name used for the Consul services. MetaKeyPodName = "pod-name" + + // DefaultGracefulPort is the default port that consul-dataplane uses for graceful shutdown. + DefaultGracefulPort = 20600 + + // DefaultGracefulShutdownPath is the default path that consul-dataplane uses for graceful shutdown. + DefaultGracefulShutdownPath = "/graceful_shutdown" ) diff --git a/control-plane/connect-inject/lifecycle/lifecycle_configuration.go b/control-plane/connect-inject/lifecycle/lifecycle_configuration.go new file mode 100644 index 0000000000..651d4eecae --- /dev/null +++ b/control-plane/connect-inject/lifecycle/lifecycle_configuration.go @@ -0,0 +1,95 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package lifecycle + +import ( + "fmt" + "strconv" + + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/common" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" + corev1 "k8s.io/api/core/v1" +) + +// Config represents configuration common to connect-inject components related to proxy lifecycle management. +type Config struct { + DefaultEnableProxyLifecycle bool + DefaultEnableShutdownDrainListeners bool + DefaultShutdownGracePeriodSeconds int + DefaultGracefulPort string + DefaultGracefulShutdownPath string +} + +// EnableProxyLifecycle returns whether proxy lifecycle management is enabled either via the default value in the meshWebhook, or if it's been +// overridden via the annotation. +func (lc Config) EnableProxyLifecycle(pod corev1.Pod) (bool, error) { + enabled := lc.DefaultEnableProxyLifecycle + if raw, ok := pod.Annotations[constants.AnnotationEnableSidecarProxyLifecycle]; ok && raw != "" { + enableProxyLifecycle, err := strconv.ParseBool(raw) + if err != nil { + return false, fmt.Errorf("%s annotation value of %s was invalid: %s", constants.AnnotationEnableSidecarProxyLifecycle, raw, err) + } + enabled = enableProxyLifecycle + } + return enabled, nil +} + +// EnableShutdownDrainListeners returns whether proxy listener draining during shutdown is enabled either via the default value in the meshWebhook, or if it's been +// overridden via the annotation. +func (lc Config) EnableShutdownDrainListeners(pod corev1.Pod) (bool, error) { + enabled := lc.DefaultEnableShutdownDrainListeners + if raw, ok := pod.Annotations[constants.AnnotationEnableSidecarProxyLifecycleShutdownDrainListeners]; ok && raw != "" { + enableShutdownDrainListeners, err := strconv.ParseBool(raw) + if err != nil { + return false, fmt.Errorf("%s annotation value of %s was invalid: %s", constants.AnnotationEnableSidecarProxyLifecycleShutdownDrainListeners, raw, err) + } + enabled = enableShutdownDrainListeners + } + return enabled, nil +} + +// ShutdownGracePeriodSeconds returns how long the sidecar proxy should wait before shutdown, either via the default value in the meshWebhook, or if it's been +// overridden via the annotation. +func (lc Config) ShutdownGracePeriodSeconds(pod corev1.Pod) (int, error) { + shutdownGracePeriodSeconds := lc.DefaultShutdownGracePeriodSeconds + if shutdownGracePeriodSecondsAnnotation, ok := pod.Annotations[constants.AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds]; ok { + val, err := strconv.ParseUint(shutdownGracePeriodSecondsAnnotation, 10, 64) + if err != nil { + return 0, fmt.Errorf("unable to parse annotation %q: %w", constants.AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds, err) + } + shutdownGracePeriodSeconds = int(val) + } + return shutdownGracePeriodSeconds, nil +} + +// GracefulPort returns the port on which consul-dataplane should serve the proxy lifecycle management HTTP endpoints, either via the default value in the meshWebhook, or +// if it's been overridden via the annotation. It also validates the port is in the unprivileged port range. +func (lc Config) GracefulPort(pod corev1.Pod) (int, error) { + anno, err := common.DetermineAndValidatePort(pod, constants.AnnotationSidecarProxyLifecycleGracefulPort, lc.DefaultGracefulPort, false) + if err != nil { + return 0, err + } + + if anno == "" { + return constants.DefaultGracefulPort, nil + } + + port, _ := strconv.Atoi(anno) + + return port, nil +} + +// GracefulShutdownPath returns the path on which consul-dataplane should serve the graceful shutdown HTTP endpoint, either via the default value in the meshWebhook, or +// if it's been overridden via the annotation. +func (lc Config) GracefulShutdownPath(pod corev1.Pod) string { + if raw, ok := pod.Annotations[constants.AnnotationSidecarProxyLifecycleGracefulShutdownPath]; ok && raw != "" { + return raw + } + + if lc.DefaultGracefulShutdownPath == "" { + return constants.DefaultGracefulShutdownPath + } + + return lc.DefaultGracefulShutdownPath +} diff --git a/control-plane/connect-inject/lifecycle/lifecycle_configuration_test.go b/control-plane/connect-inject/lifecycle/lifecycle_configuration_test.go new file mode 100644 index 0000000000..64157a3d55 --- /dev/null +++ b/control-plane/connect-inject/lifecycle/lifecycle_configuration_test.go @@ -0,0 +1,351 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package lifecycle + +import ( + "testing" + + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" + "github.com/hashicorp/consul-k8s/control-plane/namespaces" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestLifecycleConfig_EnableSidecarProxyLifecycle(t *testing.T) { + cases := []struct { + Name string + Pod func(*corev1.Pod) *corev1.Pod + LifecycleConfig Config + Expected bool + Err string + }{ + { + Name: "Sidecar proxy lifecycle management enabled via meshWebhook", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + LifecycleConfig: Config{ + DefaultEnableProxyLifecycle: true, + }, + Expected: true, + Err: "", + }, + { + Name: "Sidecar proxy lifecycle management enabled via annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationEnableSidecarProxyLifecycle] = "true" + return pod + }, + LifecycleConfig: Config{ + DefaultEnableProxyLifecycle: false, + }, + Expected: true, + Err: "", + }, + { + Name: "Sidecar proxy lifecycle management configured via invalid annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationEnableSidecarProxyLifecycle] = "not-a-bool" + return pod + }, + LifecycleConfig: Config{ + DefaultEnableProxyLifecycle: false, + }, + Expected: false, + Err: "consul.hashicorp.com/enable-sidecar-proxy-lifecycle annotation value of not-a-bool was invalid: strconv.ParseBool: parsing \"not-a-bool\": invalid syntax", + }, + } + + for _, tt := range cases { + t.Run(tt.Name, func(t *testing.T) { + require := require.New(t) + lc := tt.LifecycleConfig + + actual, err := lc.EnableProxyLifecycle(*tt.Pod(minimal())) + + if tt.Err == "" { + require.Equal(tt.Expected, actual) + require.NoError(err) + } else { + require.EqualError(err, tt.Err) + } + }) + } +} + +func TestLifecycleConfig_ShutdownDrainListeners(t *testing.T) { + cases := []struct { + Name string + Pod func(*corev1.Pod) *corev1.Pod + LifecycleConfig Config + Expected bool + Err string + }{ + { + Name: "Sidecar proxy shutdown listener draining enabled via meshWebhook", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + LifecycleConfig: Config{ + DefaultEnableShutdownDrainListeners: true, + }, + Expected: true, + Err: "", + }, + { + Name: "Sidecar proxy shutdown listener draining enabled via annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationEnableSidecarProxyLifecycleShutdownDrainListeners] = "true" + return pod + }, + LifecycleConfig: Config{ + DefaultEnableShutdownDrainListeners: false, + }, + Expected: true, + Err: "", + }, + { + Name: "Sidecar proxy shutdown listener draining configured via invalid annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationEnableSidecarProxyLifecycleShutdownDrainListeners] = "not-a-bool" + return pod + }, + Expected: false, + Err: "consul.hashicorp.com/enable-sidecar-proxy-lifecycle-shutdown-drain-listeners annotation value of not-a-bool was invalid: strconv.ParseBool: parsing \"not-a-bool\": invalid syntax", + }, + } + + for _, tt := range cases { + t.Run(tt.Name, func(t *testing.T) { + require := require.New(t) + lc := tt.LifecycleConfig + + actual, err := lc.EnableShutdownDrainListeners(*tt.Pod(minimal())) + + if tt.Err == "" { + require.Equal(tt.Expected, actual) + require.NoError(err) + } else { + require.EqualError(err, tt.Err) + } + }) + } +} + +func TestLifecycleConfig_ShutdownGracePeriodSeconds(t *testing.T) { + cases := []struct { + Name string + Pod func(*corev1.Pod) *corev1.Pod + LifecycleConfig Config + Expected int + Err string + }{ + { + Name: "Sidecar proxy shutdown grace period set via meshWebhook", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + LifecycleConfig: Config{ + DefaultShutdownGracePeriodSeconds: 10, + }, + Expected: 10, + Err: "", + }, + { + Name: "Sidecar proxy shutdown grace period set via annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds] = "20" + return pod + }, + LifecycleConfig: Config{ + DefaultShutdownGracePeriodSeconds: 10, + }, + Expected: 20, + Err: "", + }, + { + Name: "Sidecar proxy shutdown grace period configured via invalid annotation, negative number", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds] = "-1" + return pod + }, + Err: "unable to parse annotation \"consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds\": strconv.ParseUint: parsing \"-1\": invalid syntax", + }, + { + Name: "Sidecar proxy shutdown grace period configured via invalid annotation, not-parseable string", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds] = "not-int" + return pod + }, + Err: "unable to parse annotation \"consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds\": strconv.ParseUint: parsing \"not-int\": invalid syntax", + }, + } + + for _, tt := range cases { + t.Run(tt.Name, func(t *testing.T) { + require := require.New(t) + lc := tt.LifecycleConfig + + actual, err := lc.ShutdownGracePeriodSeconds(*tt.Pod(minimal())) + + if tt.Err == "" { + require.Equal(tt.Expected, actual) + require.NoError(err) + } else { + require.EqualError(err, tt.Err) + } + }) + } +} + +func TestLifecycleConfig_GracefulPort(t *testing.T) { + cases := []struct { + Name string + Pod func(*corev1.Pod) *corev1.Pod + LifecycleConfig Config + Expected int + Err string + }{ + { + Name: "Sidecar proxy lifecycle graceful port set to default", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + Expected: constants.DefaultGracefulPort, + Err: "", + }, + { + Name: "Sidecar proxy lifecycle graceful port set via meshWebhook", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + LifecycleConfig: Config{ + DefaultGracefulPort: "3000", + }, + Expected: 3000, + Err: "", + }, + { + Name: "Sidecar proxy lifecycle graceful port set via annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationSidecarProxyLifecycleGracefulPort] = "9000" + return pod + }, + LifecycleConfig: Config{ + DefaultGracefulPort: "3000", + }, + Expected: 9000, + Err: "", + }, + { + Name: "Sidecar proxy lifecycle graceful port configured via invalid annotation, negative number", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationSidecarProxyLifecycleGracefulPort] = "-1" + return pod + }, + Err: "consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-port annotation value of -1 is not in the unprivileged port range 1024-65535", + }, + { + Name: "Sidecar proxy lifecycle graceful port configured via invalid annotation, not-parseable string", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationSidecarProxyLifecycleGracefulPort] = "not-int" + return pod + }, + Err: "consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-port annotation value of not-int is not a valid integer", + }, + } + + for _, tt := range cases { + t.Run(tt.Name, func(t *testing.T) { + require := require.New(t) + lc := tt.LifecycleConfig + + actual, err := lc.GracefulPort(*tt.Pod(minimal())) + + if tt.Err == "" { + require.Equal(tt.Expected, actual) + require.NoError(err) + } else { + require.EqualError(err, tt.Err) + } + }) + } +} + +func TestLifecycleConfig_GracefulShutdownPath(t *testing.T) { + cases := []struct { + Name string + Pod func(*corev1.Pod) *corev1.Pod + LifecycleConfig Config + Expected string + Err string + }{ + { + Name: "Sidecar proxy lifecycle graceful shutdown path defaults to /graceful_shutdown", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + Expected: "/graceful_shutdown", + Err: "", + }, + { + Name: "Sidecar proxy lifecycle graceful shutdown path set via meshWebhook", + Pod: func(pod *corev1.Pod) *corev1.Pod { + return pod + }, + LifecycleConfig: Config{ + DefaultGracefulShutdownPath: "/quit", + }, + Expected: "/quit", + Err: "", + }, + { + Name: "Sidecar proxy lifecycle graceful port set via annotation", + Pod: func(pod *corev1.Pod) *corev1.Pod { + pod.Annotations[constants.AnnotationSidecarProxyLifecycleGracefulShutdownPath] = "/custom-shutdown-path" + return pod + }, + LifecycleConfig: Config{ + DefaultGracefulShutdownPath: "/quit", + }, + Expected: "/custom-shutdown-path", + Err: "", + }, + } + + for _, tt := range cases { + t.Run(tt.Name, func(t *testing.T) { + require := require.New(t) + lc := tt.LifecycleConfig + + actual := lc.GracefulShutdownPath(*tt.Pod(minimal())) + + require.Equal(tt.Expected, actual) + }) + } +} + +func minimal() *corev1.Pod { + return &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespaces.DefaultNamespace, + Name: "minimal", + Annotations: map[string]string{ + constants.AnnotationService: "foo", + }, + }, + + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "web", + }, + { + Name: "web-side", + }, + }, + }, + } +} diff --git a/control-plane/connect-inject/metrics/metrics_configuration.go b/control-plane/connect-inject/metrics/metrics_configuration.go index f5b819af3d..6f9c29c85b 100644 --- a/control-plane/connect-inject/metrics/metrics_configuration.go +++ b/control-plane/connect-inject/metrics/metrics_configuration.go @@ -98,13 +98,13 @@ func (mc Config) EnableMetricsMerging(pod corev1.Pod) (bool, error) { // MergedMetricsPort returns the port to run the merged metrics server on, either via the default value in the meshWebhook, // or if it's been overridden via the annotation. It also validates the port is in the unprivileged port range. func (mc Config) MergedMetricsPort(pod corev1.Pod) (string, error) { - return determineAndValidatePort(pod, constants.AnnotationMergedMetricsPort, mc.DefaultMergedMetricsPort, false) + return common.DetermineAndValidatePort(pod, constants.AnnotationMergedMetricsPort, mc.DefaultMergedMetricsPort, false) } // PrometheusScrapePort returns the port for Prometheus to scrape from, either via the default value in the meshWebhook, or // if it's been overridden via the annotation. It also validates the port is in the unprivileged port range. func (mc Config) PrometheusScrapePort(pod corev1.Pod) (string, error) { - return determineAndValidatePort(pod, constants.AnnotationPrometheusScrapePort, mc.DefaultPrometheusScrapePort, false) + return common.DetermineAndValidatePort(pod, constants.AnnotationPrometheusScrapePort, mc.DefaultPrometheusScrapePort, false) } // PrometheusScrapePath returns the path for Prometheus to scrape from, either via the default value in the meshWebhook, or @@ -133,14 +133,14 @@ func (mc Config) ServiceMetricsPort(pod corev1.Pod) (string, error) { // written their service in such a way that it expects to be able to use // privileged ports. So, the port metrics are exposed on the service can // be privileged. - return determineAndValidatePort(pod, constants.AnnotationServiceMetricsPort, raw, true) + return common.DetermineAndValidatePort(pod, constants.AnnotationServiceMetricsPort, raw, true) } // If the annotationPort is not set, the serviceMetrics port will be 0 // unless overridden by the service-metrics-port annotation. If the service // metrics port is 0, the consul sidecar will not run a merged metrics // server. - return determineAndValidatePort(pod, constants.AnnotationServiceMetricsPort, "0", true) + return common.DetermineAndValidatePort(pod, constants.AnnotationServiceMetricsPort, "0", true) } // ServiceMetricsPath returns a default of /metrics, or overrides @@ -180,37 +180,3 @@ func (mc Config) ShouldRunMergedMetricsServer(pod corev1.Pod) (bool, error) { } return false, nil } - -// determineAndValidatePort behaves as follows: -// If the annotation exists, validate the port and return it. -// If the annotation does not exist, return the default port. -// If the privileged flag is true, it will allow the port to be in the -// privileged port range of 1-1023. Otherwise, it will only allow ports in the -// unprivileged range of 1024-65535. -func determineAndValidatePort(pod corev1.Pod, annotation string, defaultPort string, privileged bool) (string, error) { - if raw, ok := pod.Annotations[annotation]; ok && raw != "" { - port, err := common.PortValue(pod, raw) - if err != nil { - return "", fmt.Errorf("%s annotation value of %s is not a valid integer", annotation, raw) - } - - if privileged && (port < 1 || port > 65535) { - return "", fmt.Errorf("%s annotation value of %d is not in the valid port range 1-65535", annotation, port) - } else if !privileged && (port < 1024 || port > 65535) { - return "", fmt.Errorf("%s annotation value of %d is not in the unprivileged port range 1024-65535", annotation, port) - } - - // If the annotation exists, return the validated port. - return fmt.Sprint(port), nil - } - - // If the annotation does not exist, return the default. - if defaultPort != "" { - port, err := common.PortValue(pod, defaultPort) - if err != nil { - return "", fmt.Errorf("%s is not a valid port on the pod %s", defaultPort, pod.Name) - } - return fmt.Sprint(port), nil - } - return "", nil -} diff --git a/control-plane/connect-inject/metrics/metrics_configuration_test.go b/control-plane/connect-inject/metrics/metrics_configuration_test.go index ec19d4f55a..12045e28d1 100644 --- a/control-plane/connect-inject/metrics/metrics_configuration_test.go +++ b/control-plane/connect-inject/metrics/metrics_configuration_test.go @@ -307,149 +307,6 @@ func TestMetricsConfigShouldRunMergedMetricsServer(t *testing.T) { } } -// Tests determineAndValidatePort, which in turn tests the -// PrometheusScrapePort() and MergedMetricsPort() functions because their logic -// is just to call out to determineAndValidatePort(). -func TestMetricsConfigDetermineAndValidatePort(t *testing.T) { - cases := []struct { - Name string - Pod func(*corev1.Pod) *corev1.Pod - Annotation string - Privileged bool - DefaultPort string - Expected string - Err string - }{ - { - Name: "Valid annotation", - Pod: func(pod *corev1.Pod) *corev1.Pod { - pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "1234" - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: false, - Expected: "1234", - Err: "", - }, - { - Name: "Uses default when there's no annotation", - Pod: func(pod *corev1.Pod) *corev1.Pod { - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: false, - DefaultPort: "4321", - Expected: "4321", - Err: "", - }, - { - Name: "Gets the value of the named default port when there's no annotation", - Pod: func(pod *corev1.Pod) *corev1.Pod { - pod.Spec.Containers[0].Ports = []corev1.ContainerPort{ - { - Name: "web-port", - ContainerPort: 2222, - }, - } - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: false, - DefaultPort: "web-port", - Expected: "2222", - Err: "", - }, - { - Name: "Errors if the named default port doesn't exist on the pod", - Pod: func(pod *corev1.Pod) *corev1.Pod { - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: false, - DefaultPort: "web-port", - Expected: "", - Err: "web-port is not a valid port on the pod minimal", - }, - { - Name: "Gets the value of the named port", - Pod: func(pod *corev1.Pod) *corev1.Pod { - pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "web-port" - pod.Spec.Containers[0].Ports = []corev1.ContainerPort{ - { - Name: "web-port", - ContainerPort: 2222, - }, - } - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: false, - DefaultPort: "4321", - Expected: "2222", - Err: "", - }, - { - Name: "Invalid annotation (not an integer)", - Pod: func(pod *corev1.Pod) *corev1.Pod { - pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "not-an-int" - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: false, - Expected: "", - Err: "consul.hashicorp.com/test-annotation-port annotation value of not-an-int is not a valid integer", - }, - { - Name: "Invalid annotation (integer not in port range)", - Pod: func(pod *corev1.Pod) *corev1.Pod { - pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "100000" - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: true, - Expected: "", - Err: "consul.hashicorp.com/test-annotation-port annotation value of 100000 is not in the valid port range 1-65535", - }, - { - Name: "Invalid annotation (integer not in unprivileged port range)", - Pod: func(pod *corev1.Pod) *corev1.Pod { - pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "22" - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: false, - Expected: "", - Err: "consul.hashicorp.com/test-annotation-port annotation value of 22 is not in the unprivileged port range 1024-65535", - }, - { - Name: "Privileged ports allowed", - Pod: func(pod *corev1.Pod) *corev1.Pod { - pod.Annotations["consul.hashicorp.com/test-annotation-port"] = "22" - return pod - }, - Annotation: "consul.hashicorp.com/test-annotation-port", - Privileged: true, - Expected: "22", - Err: "", - }, - } - - for _, tt := range cases { - t.Run(tt.Name, func(t *testing.T) { - require := require.New(t) - - actual, err := determineAndValidatePort(*tt.Pod(minimal()), tt.Annotation, tt.DefaultPort, tt.Privileged) - - if tt.Err == "" { - require.NoError(err) - require.Equal(tt.Expected, actual) - } else { - require.EqualError(err, tt.Err) - } - }) - } -} - // Tests MergedMetricsServerConfiguration happy path and error case not covered by other Config tests. func TestMetricsConfigMergedMetricsServerConfiguration(t *testing.T) { cases := []struct { diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go index fe37720b7d..68f57ed061 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go @@ -247,6 +247,45 @@ func (w *MeshWebhook) getContainerSidecarArgs(namespace corev1.Namespace, mpi mu args = append(args, fmt.Sprintf("-envoy-admin-bind-port=%d", 19000+mpi.serviceIndex)) } + // The consul-dataplane HTTP listener always starts for graceful shutdown. To avoid port conflicts, the + // graceful port always needs to be set + gracefulPort, err := w.LifecycleConfig.GracefulPort(pod) + if err != nil { + return nil, fmt.Errorf("unable to determine proxy lifecycle graceful port: %w", err) + } + + // To avoid conflicts + if mpi.serviceName != "" { + gracefulPort = gracefulPort + mpi.serviceIndex + } + args = append(args, fmt.Sprintf("-graceful-port=%d", gracefulPort)) + + enableProxyLifecycle, err := w.LifecycleConfig.EnableProxyLifecycle(pod) + if err != nil { + return nil, fmt.Errorf("unable to determine if proxy lifecycle management is enabled: %w", err) + } + if enableProxyLifecycle { + shutdownDrainListeners, err := w.LifecycleConfig.EnableShutdownDrainListeners(pod) + if err != nil { + return nil, fmt.Errorf("unable to determine if proxy lifecycle shutdown listener draining is enabled: %w", err) + } + if shutdownDrainListeners { + args = append(args, "-shutdown-drain-listeners") + } + + shutdownGracePeriodSeconds, err := w.LifecycleConfig.ShutdownGracePeriodSeconds(pod) + if err != nil { + return nil, fmt.Errorf("unable to determine proxy lifecycle shutdown grace period: %w", err) + } + args = append(args, fmt.Sprintf("-shutdown-grace-period-seconds=%d", shutdownGracePeriodSeconds)) + + gracefulShutdownPath := w.LifecycleConfig.GracefulShutdownPath(pod) + if err != nil { + return nil, fmt.Errorf("unable to determine proxy lifecycle graceful shutdown path: %w", err) + } + args = append(args, fmt.Sprintf("-graceful-shutdown-path=%s", gracefulShutdownPath)) + } + // Set a default scrape path that can be overwritten by the annotation. prometheusScrapePath := w.MetricsConfig.PrometheusScrapePath(pod) args = append(args, "-telemetry-prom-scrape-path="+prometheusScrapePath) diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go index 0860293352..d83b094d99 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go @@ -10,6 +10,7 @@ import ( "testing" "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/lifecycle" "github.com/hashicorp/consul-k8s/control-plane/consul" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" @@ -28,20 +29,20 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { }{ "default": { webhookSetupFunc: nil, - additionalExpCmdArgs: " -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with custom gRPC port": { webhookSetupFunc: func(w *MeshWebhook) { w.ConsulConfig.GRPCPort = 8602 }, - additionalExpCmdArgs: " -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with ACLs": { webhookSetupFunc: func(w *MeshWebhook) { w.AuthMethod = "test-auth-method" }, additionalExpCmdArgs: " -credential-type=login -login-auth-method=test-auth-method -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token " + - "-login-meta=pod=k8snamespace/test-pod -tls-disabled -telemetry-prom-scrape-path=/metrics", + "-login-meta=pod=k8snamespace/test-pod -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with ACLs and namespace mirroring": { webhookSetupFunc: func(w *MeshWebhook) { @@ -50,7 +51,7 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.EnableK8SNSMirroring = true }, additionalExpCmdArgs: " -credential-type=login -login-auth-method=test-auth-method -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token " + - "-login-meta=pod=k8snamespace/test-pod -login-namespace=default -service-namespace=k8snamespace -tls-disabled -telemetry-prom-scrape-path=/metrics", + "-login-meta=pod=k8snamespace/test-pod -login-namespace=default -service-namespace=k8snamespace -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with ACLs and single destination namespace": { webhookSetupFunc: func(w *MeshWebhook) { @@ -59,7 +60,7 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.ConsulDestinationNamespace = "test-ns" }, additionalExpCmdArgs: " -credential-type=login -login-auth-method=test-auth-method -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token " + - "-login-meta=pod=k8snamespace/test-pod -login-namespace=test-ns -service-namespace=test-ns -tls-disabled -telemetry-prom-scrape-path=/metrics", + "-login-meta=pod=k8snamespace/test-pod -login-namespace=test-ns -service-namespace=test-ns -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with ACLs and partitions": { webhookSetupFunc: func(w *MeshWebhook) { @@ -67,7 +68,7 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.ConsulPartition = "test-part" }, additionalExpCmdArgs: " -credential-type=login -login-auth-method=test-auth-method -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token " + - "-login-meta=pod=k8snamespace/test-pod -login-partition=test-part -service-partition=test-part -tls-disabled -telemetry-prom-scrape-path=/metrics", + "-login-meta=pod=k8snamespace/test-pod -login-partition=test-part -service-partition=test-part -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with TLS and CA cert provided": { webhookSetupFunc: func(w *MeshWebhook) { @@ -75,28 +76,28 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.ConsulTLSServerName = "server.dc1.consul" w.ConsulCACert = "consul-ca-cert" }, - additionalExpCmdArgs: " -tls-server-name=server.dc1.consul -ca-certs=/consul/connect-inject/consul-ca.pem -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -tls-server-name=server.dc1.consul -ca-certs=/consul/connect-inject/consul-ca.pem -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with TLS and no CA cert provided": { webhookSetupFunc: func(w *MeshWebhook) { w.TLSEnabled = true w.ConsulTLSServerName = "server.dc1.consul" }, - additionalExpCmdArgs: " -tls-server-name=server.dc1.consul -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -tls-server-name=server.dc1.consul -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with single destination namespace": { webhookSetupFunc: func(w *MeshWebhook) { w.EnableNamespaces = true w.ConsulDestinationNamespace = "consul-namespace" }, - additionalExpCmdArgs: " -service-namespace=consul-namespace -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -service-namespace=consul-namespace -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with namespace mirroring": { webhookSetupFunc: func(w *MeshWebhook) { w.EnableNamespaces = true w.EnableK8SNSMirroring = true }, - additionalExpCmdArgs: " -service-namespace=k8snamespace -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -service-namespace=k8snamespace -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with namespace mirroring prefix": { webhookSetupFunc: func(w *MeshWebhook) { @@ -104,38 +105,38 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.EnableK8SNSMirroring = true w.K8SNSMirroringPrefix = "foo-" }, - additionalExpCmdArgs: " -service-namespace=foo-k8snamespace -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -service-namespace=foo-k8snamespace -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with partitions": { webhookSetupFunc: func(w *MeshWebhook) { w.ConsulPartition = "partition-1" }, - additionalExpCmdArgs: " -service-partition=partition-1 -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -service-partition=partition-1 -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with different log level": { webhookSetupFunc: func(w *MeshWebhook) { w.LogLevel = "debug" }, - additionalExpCmdArgs: " -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with different log level and log json": { webhookSetupFunc: func(w *MeshWebhook) { w.LogLevel = "debug" w.LogJSON = true }, - additionalExpCmdArgs: " -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "skip server watch enabled": { webhookSetupFunc: func(w *MeshWebhook) { w.SkipServerWatch = true }, - additionalExpCmdArgs: " -server-watch-disabled=true -tls-disabled -telemetry-prom-scrape-path=/metrics", + additionalExpCmdArgs: " -server-watch-disabled=true -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "custom prometheus scrape path": { webhookSetupFunc: func(w *MeshWebhook) { w.MetricsConfig.DefaultPrometheusScrapePath = "/scrape-path" // Simulate what would be passed as a flag }, - additionalExpCmdArgs: " -tls-disabled -telemetry-prom-scrape-path=/scrape-path", + additionalExpCmdArgs: " -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/scrape-path", }, } @@ -622,18 +623,18 @@ func TestHandlerConsulDataplaneSidecar_Multiport(t *testing.T) { } expArgs := []string{ "-addresses 1.1.1.1 -grpc-port=8502 -proxy-service-id-path=/consul/connect-inject/proxyid-web " + - "-log-level=info -log-json=false -envoy-concurrency=0 -tls-disabled -envoy-admin-bind-port=19000 -telemetry-prom-scrape-path=/metrics -- --base-id 0", + "-log-level=info -log-json=false -envoy-concurrency=0 -tls-disabled -envoy-admin-bind-port=19000 -graceful-port=20600 -telemetry-prom-scrape-path=/metrics -- --base-id 0", "-addresses 1.1.1.1 -grpc-port=8502 -proxy-service-id-path=/consul/connect-inject/proxyid-web-admin " + - "-log-level=info -log-json=false -envoy-concurrency=0 -tls-disabled -envoy-admin-bind-port=19001 -telemetry-prom-scrape-path=/metrics -- --base-id 1", + "-log-level=info -log-json=false -envoy-concurrency=0 -tls-disabled -envoy-admin-bind-port=19001 -graceful-port=20601 -telemetry-prom-scrape-path=/metrics -- --base-id 1", } if aclsEnabled { expArgs = []string{ "-addresses 1.1.1.1 -grpc-port=8502 -proxy-service-id-path=/consul/connect-inject/proxyid-web " + "-log-level=info -log-json=false -envoy-concurrency=0 -credential-type=login -login-auth-method=test-auth-method " + - "-login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token -login-meta=pod=k8snamespace/test-pod -tls-disabled -envoy-admin-bind-port=19000 -telemetry-prom-scrape-path=/metrics -- --base-id 0", + "-login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token -login-meta=pod=k8snamespace/test-pod -tls-disabled -envoy-admin-bind-port=19000 -graceful-port=20600 -telemetry-prom-scrape-path=/metrics -- --base-id 0", "-addresses 1.1.1.1 -grpc-port=8502 -proxy-service-id-path=/consul/connect-inject/proxyid-web-admin " + "-log-level=info -log-json=false -envoy-concurrency=0 -credential-type=login -login-auth-method=test-auth-method " + - "-login-bearer-token-path=/consul/serviceaccount-web-admin/token -login-meta=pod=k8snamespace/test-pod -tls-disabled -envoy-admin-bind-port=19001 -telemetry-prom-scrape-path=/metrics -- --base-id 1", + "-login-bearer-token-path=/consul/serviceaccount-web-admin/token -login-meta=pod=k8snamespace/test-pod -tls-disabled -envoy-admin-bind-port=19001 -graceful-port=20601 -telemetry-prom-scrape-path=/metrics -- --base-id 1", } } expSAVolumeMounts := []corev1.VolumeMount{ @@ -1299,6 +1300,156 @@ func TestHandlerConsulDataplaneSidecar_Metrics(t *testing.T) { } } +func TestHandlerConsulDataplaneSidecar_Lifecycle(t *testing.T) { + gracefulShutdownSeconds := 10 + gracefulPort := "20307" + gracefulShutdownPath := "/exit" + + cases := []struct { + name string + webhook MeshWebhook + annotations map[string]string + expCmdArgs string + expErr string + }{ + { + name: "no defaults, no annotations", + webhook: MeshWebhook{}, + annotations: nil, + expCmdArgs: "", + }, + { + name: "all defaults, no annotations", + webhook: MeshWebhook{ + LifecycleConfig: lifecycle.Config{ + DefaultEnableProxyLifecycle: true, + DefaultEnableShutdownDrainListeners: true, + DefaultShutdownGracePeriodSeconds: gracefulShutdownSeconds, + DefaultGracefulPort: gracefulPort, + DefaultGracefulShutdownPath: gracefulShutdownPath, + }, + }, + annotations: nil, + expCmdArgs: "graceful-port=20307 -shutdown-drain-listeners -shutdown-grace-period-seconds=10 -graceful-shutdown-path=/exit", + }, + { + name: "no defaults, all annotations", + webhook: MeshWebhook{}, + annotations: map[string]string{ + constants.AnnotationEnableSidecarProxyLifecycle: "true", + constants.AnnotationEnableSidecarProxyLifecycleShutdownDrainListeners: "true", + constants.AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds: fmt.Sprint(gracefulShutdownSeconds), + constants.AnnotationSidecarProxyLifecycleGracefulPort: gracefulPort, + constants.AnnotationSidecarProxyLifecycleGracefulShutdownPath: gracefulShutdownPath, + }, + expCmdArgs: "-graceful-port=20307 -shutdown-drain-listeners -shutdown-grace-period-seconds=10 -graceful-shutdown-path=/exit", + }, + { + name: "annotations override defaults", + webhook: MeshWebhook{ + LifecycleConfig: lifecycle.Config{ + DefaultEnableProxyLifecycle: false, + DefaultEnableShutdownDrainListeners: true, + DefaultShutdownGracePeriodSeconds: gracefulShutdownSeconds, + DefaultGracefulPort: gracefulPort, + DefaultGracefulShutdownPath: gracefulShutdownPath, + }, + }, + annotations: map[string]string{ + constants.AnnotationEnableSidecarProxyLifecycle: "true", + constants.AnnotationEnableSidecarProxyLifecycleShutdownDrainListeners: "false", + constants.AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds: fmt.Sprint(gracefulShutdownSeconds + 5), + constants.AnnotationSidecarProxyLifecycleGracefulPort: "20317", + constants.AnnotationSidecarProxyLifecycleGracefulShutdownPath: "/foo", + }, + expCmdArgs: "-graceful-port=20317 -shutdown-grace-period-seconds=15 -graceful-shutdown-path=/foo", + }, + { + name: "lifecycle disabled, no annotations", + webhook: MeshWebhook{ + LifecycleConfig: lifecycle.Config{ + DefaultEnableProxyLifecycle: false, + DefaultEnableShutdownDrainListeners: true, + DefaultShutdownGracePeriodSeconds: gracefulShutdownSeconds, + DefaultGracefulPort: gracefulPort, + DefaultGracefulShutdownPath: gracefulShutdownPath, + }, + }, + annotations: nil, + expCmdArgs: "-graceful-port=20307", + }, + { + name: "lifecycle enabled, defaults omited, no annotations", + webhook: MeshWebhook{ + LifecycleConfig: lifecycle.Config{ + DefaultEnableProxyLifecycle: true, + }, + }, + annotations: nil, + expCmdArgs: "", + }, + { + name: "annotations disable lifecycle default", + webhook: MeshWebhook{ + LifecycleConfig: lifecycle.Config{ + DefaultEnableProxyLifecycle: true, + DefaultEnableShutdownDrainListeners: true, + DefaultShutdownGracePeriodSeconds: gracefulShutdownSeconds, + DefaultGracefulPort: gracefulPort, + DefaultGracefulShutdownPath: gracefulShutdownPath, + }, + }, + annotations: map[string]string{ + constants.AnnotationEnableSidecarProxyLifecycle: "false", + }, + expCmdArgs: "-graceful-port=20307", + }, + { + name: "annotations skip graceful shutdown", + webhook: MeshWebhook{ + LifecycleConfig: lifecycle.Config{ + DefaultEnableProxyLifecycle: false, + DefaultEnableShutdownDrainListeners: true, + DefaultShutdownGracePeriodSeconds: gracefulShutdownSeconds, + }, + }, + annotations: map[string]string{ + constants.AnnotationEnableSidecarProxyLifecycle: "false", + constants.AnnotationEnableSidecarProxyLifecycleShutdownDrainListeners: "false", + constants.AnnotationSidecarProxyLifecycleShutdownGracePeriodSeconds: "0", + }, + expCmdArgs: "", + }, + } + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + c.webhook.ConsulConfig = &consul.Config{HTTPPort: 8500, GRPCPort: 8502} + require := require.New(t) + pod := corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: c.annotations, + }, + + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "web", + }, + }, + }, + } + container, err := c.webhook.consulDataplaneSidecar(testNS, pod, multiPortInfo{}) + if c.expErr != "" { + require.NotNil(err) + require.Contains(err.Error(), c.expErr) + } else { + require.NoError(err) + require.Contains(strings.Join(container.Args, " "), c.expCmdArgs) + } + }) + } +} + // boolPtr returns pointer to b. func boolPtr(b bool) *bool { return &b diff --git a/control-plane/connect-inject/webhook/mesh_webhook.go b/control-plane/connect-inject/webhook/mesh_webhook.go index 96c73d93d4..d97bca6646 100644 --- a/control-plane/connect-inject/webhook/mesh_webhook.go +++ b/control-plane/connect-inject/webhook/mesh_webhook.go @@ -17,6 +17,7 @@ import ( "github.com/go-logr/logr" "github.com/hashicorp/consul-k8s/control-plane/connect-inject/common" "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/lifecycle" "github.com/hashicorp/consul-k8s/control-plane/connect-inject/metrics" "github.com/hashicorp/consul-k8s/control-plane/consul" "github.com/hashicorp/consul-k8s/control-plane/namespaces" @@ -151,6 +152,10 @@ type MeshWebhook struct { DefaultProxyMemoryRequest resource.Quantity DefaultProxyMemoryLimit resource.Quantity + // LifecycleConfig contains proxy lifecycle management configuration from the inject-connect command and has methods to determine whether + // configuration should come from the default flags or annotations. The meshWebhook uses this to configure container sidecar proxy args. + LifecycleConfig lifecycle.Config + // Default Envoy concurrency flag, this is the number of worker threads to be used by the proxy. DefaultEnvoyProxyConcurrency int @@ -306,6 +311,7 @@ func (w *MeshWebhook) Handle(ctx context.Context, req admission.Request) admissi w.Log.Error(err, "error configuring injection sidecar container", "request name", req.Name) return admission.Errored(http.StatusInternalServerError, fmt.Errorf("error configuring injection sidecar container: %s", err)) } + // TODO: invert to start the Envoy sidecar before the application container pod.Spec.Containers = append(pod.Spec.Containers, envoySidecar) } else { // For multi port pods, check for unsupported cases, mount all relevant service account tokens, and mount an init @@ -376,6 +382,8 @@ func (w *MeshWebhook) Handle(ctx context.Context, req admission.Request) admissi w.Log.Error(err, "error configuring injection sidecar container", "request name", req.Name) return admission.Errored(http.StatusInternalServerError, fmt.Errorf("error configuring injection sidecar container: %s", err)) } + // TODO: invert to start the Envoy sidecar container before the + // application container pod.Spec.Containers = append(pod.Spec.Containers, envoySidecar) } } diff --git a/control-plane/subcommand/inject-connect/command.go b/control-plane/subcommand/inject-connect/command.go index 8bada415db..6767e60130 100644 --- a/control-plane/subcommand/inject-connect/command.go +++ b/control-plane/subcommand/inject-connect/command.go @@ -19,8 +19,10 @@ import ( gatewaycontrollers "github.com/hashicorp/consul-k8s/control-plane/api-gateway/controllers" apicommon "github.com/hashicorp/consul-k8s/control-plane/api/common" "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" "github.com/hashicorp/consul-k8s/control-plane/connect-inject/controllers/endpoints" "github.com/hashicorp/consul-k8s/control-plane/connect-inject/controllers/peering" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/lifecycle" "github.com/hashicorp/consul-k8s/control-plane/connect-inject/metrics" "github.com/hashicorp/consul-k8s/control-plane/connect-inject/webhook" "github.com/hashicorp/consul-k8s/control-plane/controllers" @@ -86,6 +88,13 @@ type Command struct { flagDefaultSidecarProxyMemoryRequest string flagDefaultEnvoyProxyConcurrency int + // Proxy lifecycle settings. + flagDefaultEnableSidecarProxyLifecycle bool + flagDefaultEnableSidecarProxyLifecycleShutdownDrainListeners bool + flagDefaultSidecarProxyLifecycleShutdownGracePeriodSeconds int + flagDefaultSidecarProxyLifecycleGracefulPort string + flagDefaultSidecarProxyLifecycleGracefulShutdownPath string + // Metrics settings. flagDefaultEnableMetrics bool flagEnableGatewayMetrics bool @@ -220,6 +229,13 @@ func (c *Command) init() { c.flagSet.StringVar(&c.flagDefaultSidecarProxyMemoryRequest, "default-sidecar-proxy-memory-request", "", "Default sidecar proxy memory request.") c.flagSet.StringVar(&c.flagDefaultSidecarProxyMemoryLimit, "default-sidecar-proxy-memory-limit", "", "Default sidecar proxy memory limit.") + // Proxy lifecycle setting flags. + c.flagSet.BoolVar(&c.flagDefaultEnableSidecarProxyLifecycle, "default-enable-sidecar-proxy-lifecycle", false, "Default for enabling sidecar proxy lifecycle management.") + c.flagSet.BoolVar(&c.flagDefaultEnableSidecarProxyLifecycleShutdownDrainListeners, "default-enable-sidecar-proxy-lifecycle-shutdown-drain-listeners", false, "Default for enabling sidecar proxy listener draining of inbound connections during shutdown.") + c.flagSet.IntVar(&c.flagDefaultSidecarProxyLifecycleShutdownGracePeriodSeconds, "default-sidecar-proxy-lifecycle-shutdown-grace-period-seconds", 0, "Default sidecar proxy shutdown grace period in seconds.") + c.flagSet.StringVar(&c.flagDefaultSidecarProxyLifecycleGracefulPort, "default-sidecar-proxy-lifecycle-graceful-port", strconv.Itoa(constants.DefaultGracefulPort), "Default port for sidecar proxy lifecycle management HTTP endpoints.") + c.flagSet.StringVar(&c.flagDefaultSidecarProxyLifecycleGracefulShutdownPath, "default-sidecar-proxy-lifecycle-graceful-shutdown-path", "/graceful_shutdown", "Default sidecar proxy lifecycle management graceful shutdown path.") + // Metrics setting flags. c.flagSet.BoolVar(&c.flagDefaultEnableMetrics, "default-enable-metrics", false, "Default for enabling connect service metrics.") c.flagSet.BoolVar(&c.flagEnableGatewayMetrics, "enable-gateway-metrics", false, "Allows enabling Consul gateway metrics.") @@ -422,6 +438,14 @@ func (c *Command) Run(args []string) int { return 1 } + lifecycleConfig := lifecycle.Config{ + DefaultEnableProxyLifecycle: c.flagDefaultEnableSidecarProxyLifecycle, + DefaultEnableShutdownDrainListeners: c.flagDefaultEnableSidecarProxyLifecycleShutdownDrainListeners, + DefaultShutdownGracePeriodSeconds: c.flagDefaultSidecarProxyLifecycleShutdownGracePeriodSeconds, + DefaultGracefulPort: c.flagDefaultSidecarProxyLifecycleGracefulPort, + DefaultGracefulShutdownPath: c.flagDefaultSidecarProxyLifecycleGracefulShutdownPath, + } + metricsConfig := metrics.Config{ DefaultEnableMetrics: c.flagDefaultEnableMetrics, EnableGatewayMetrics: c.flagEnableGatewayMetrics, @@ -725,6 +749,7 @@ func (c *Command) Run(args []string) int { DefaultProxyMemoryRequest: sidecarProxyMemoryRequest, DefaultProxyMemoryLimit: sidecarProxyMemoryLimit, DefaultEnvoyProxyConcurrency: c.flagDefaultEnvoyProxyConcurrency, + LifecycleConfig: lifecycleConfig, MetricsConfig: metricsConfig, InitContainerResources: initResources, ConsulPartition: c.consul.Partition, From d3f9b670ab8055f0fc8ea4061c2d3c40abeb047f Mon Sep 17 00:00:00 2001 From: David Yu Date: Tue, 27 Jun 2023 19:15:51 -0700 Subject: [PATCH 045/120] PR breaking change release note change (#2469) * Add breaking change to release notes --- .changelog/2392.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.changelog/2392.txt b/.changelog/2392.txt index e15ef152b1..e268c796ff 100644 --- a/.changelog/2392.txt +++ b/.changelog/2392.txt @@ -1,3 +1,6 @@ +```release-note:breaking-change +control-plane: All policies managed by consul-k8s will now be updated on upgrade. If you previously edited the policies after install, your changes will be overwritten. +``` ```release-note:bug -control-plane: Always update ACL policies upon upgrade -``` \ No newline at end of file +control-plane: Always update ACL policies upon upgrade. +``` From 920ee3233d41792134a02f7a0e9e1d2d5ed4482d Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Wed, 28 Jun 2023 12:53:41 -0400 Subject: [PATCH 046/120] Adds back gateway controller halting integration test (#2412) Co-authored-by: John Maguire --- .../api-gateway/binding/route_binding.go | 2 +- .../gateway_controller_integration_test.go | 1320 +++++++++++++++++ 2 files changed, 1321 insertions(+), 1 deletion(-) create mode 100644 control-plane/api-gateway/controllers/gateway_controller_integration_test.go diff --git a/control-plane/api-gateway/binding/route_binding.go b/control-plane/api-gateway/binding/route_binding.go index 93e68241a0..36fcda0204 100644 --- a/control-plane/api-gateway/binding/route_binding.go +++ b/control-plane/api-gateway/binding/route_binding.go @@ -457,7 +457,7 @@ func consulCondition(generation int64, status api.ConfigEntryStatus) *metav1.Con for _, c := range status.Conditions { // we only care about the top-level status that isn't in reference // to a resource. - if c.Type == "Accepted" && c.Resource.Name == "" { + if c.Type == "Accepted" && (c.Resource == nil || c.Resource.Name == "") { return &metav1.Condition{ Type: "ConsulAccepted", Reason: c.Reason, diff --git a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go new file mode 100644 index 0000000000..b423ae54e7 --- /dev/null +++ b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go @@ -0,0 +1,1320 @@ +package controllers + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "fmt" + "math/big" + "sync" + "testing" + "time" + + mapset "github.com/deckarep/golang-set" + logrtest "github.com/go-logr/logr/testr" + "github.com/stretchr/testify/require" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/client/fake" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + + "github.com/hashicorp/consul-k8s/control-plane/api-gateway/cache" + "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" + "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" + "github.com/hashicorp/consul-k8s/control-plane/helper/test" + "github.com/hashicorp/consul/api" +) + +func TestControllerDoesNotInfinitelyReconcile(t *testing.T) { + s := runtime.NewScheme() + require.NoError(t, clientgoscheme.AddToScheme(s)) + require.NoError(t, gwv1alpha2.Install(s)) + require.NoError(t, gwv1beta1.Install(s)) + require.NoError(t, v1alpha1.AddToScheme(s)) + + testCases := map[string]struct { + namespace string + certFn func(*testing.T, context.Context, client.WithWatch, string) *corev1.Secret + gwFn func(*testing.T, context.Context, client.WithWatch, string) *gwv1beta1.Gateway + httpRouteFn func(*testing.T, context.Context, client.WithWatch, *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute + tcpRouteFn func(*testing.T, context.Context, client.WithWatch, *gwv1beta1.Gateway) *v1alpha2.TCPRoute + }{ + "all fields set": { + namespace: "consul", + certFn: createCert, + gwFn: createAllFieldsSetAPIGW, + httpRouteFn: createAllFieldsSetHTTPRoute, + tcpRouteFn: createAllFieldsSetTCPRoute, + }, + "minimal fields set": { + namespace: "", + certFn: createCert, + gwFn: minimalFieldsSetAPIGW, + httpRouteFn: minimalFieldsSetHTTPRoute, + tcpRouteFn: minimalFieldsSetTCPRoute, + }, + "funky casing to test normalization doesnt cause infinite reconciliation": { + namespace: "", + certFn: createCert, + gwFn: createFunkyCasingFieldsAPIGW, + httpRouteFn: createFunkyCasingFieldsHTTPRoute, + tcpRouteFn: createFunkyCasingFieldsTCPRoute, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + k8sClient := registerFieldIndexersForTest(fake.NewClientBuilder().WithScheme(s)).Build() + consulTestServerClient := test.TestServerWithMockConnMgrWatcher(t, nil) + ctx, cancel := context.WithCancel(context.Background()) + + t.Cleanup(func() { + cancel() + }) + logger := logrtest.New(t) + + cacheCfg := cache.Config{ + ConsulClientConfig: consulTestServerClient.Cfg, + ConsulServerConnMgr: consulTestServerClient.Watcher, + Logger: logger, + } + resourceCache := cache.New(cacheCfg) + + gwCache := cache.NewGatewayCache(ctx, cacheCfg) + + gwCtrl := GatewayController{ + HelmConfig: common.HelmConfig{}, + Log: logger, + Translator: common.ResourceTranslator{}, + cache: resourceCache, + gatewayCache: gwCache, + Client: k8sClient, + allowK8sNamespacesSet: mapset.NewSet(), + denyK8sNamespacesSet: mapset.NewSet(), + } + + go func() { + resourceCache.Run(ctx) + }() + + resourceCache.WaitSynced(ctx) + + gwSub := resourceCache.Subscribe(ctx, api.APIGateway, gwCtrl.transformConsulGateway) + httpRouteSub := resourceCache.Subscribe(ctx, api.HTTPRoute, gwCtrl.transformConsulHTTPRoute(ctx)) + tcpRouteSub := resourceCache.Subscribe(ctx, api.TCPRoute, gwCtrl.transformConsulTCPRoute(ctx)) + inlineCertSub := resourceCache.Subscribe(ctx, api.InlineCertificate, gwCtrl.transformConsulInlineCertificate(ctx)) + + cert := tc.certFn(t, ctx, k8sClient, tc.namespace) + k8sGWObj := tc.gwFn(t, ctx, k8sClient, tc.namespace) + + // reconcile so we add the finalizer + _, err := gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + Name: k8sGWObj.Name, + }, + }) + require.NoError(t, err) + + // reconcile again so that we get the creation with the finalizer + _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + Name: k8sGWObj.Name, + }, + }) + require.NoError(t, err) + + httpRouteObj := tc.httpRouteFn(t, ctx, k8sClient, k8sGWObj) + tcpRouteObj := tc.tcpRouteFn(t, ctx, k8sClient, k8sGWObj) + + // reconcile again so that we get the route bound to the gateway + _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + Name: k8sGWObj.Name, + }, + }) + require.NoError(t, err) + + // reconcile again so that we get the route bound to the gateway + _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + Name: k8sGWObj.Name, + }, + }) + require.NoError(t, err) + + wg := &sync.WaitGroup{} + // we never get the event from the cert because when it's created there are no gateways that reference it + wg.Add(3) + go func(w *sync.WaitGroup) { + gwDone := false + httpRouteDone := false + tcpRouteDone := false + for { + // get the creation events from the upsert and then continually read from channel so we dont block other subs + select { + case <-ctx.Done(): + return + case <-gwSub.Events(): + if !gwDone { + gwDone = true + wg.Done() + } + case <-httpRouteSub.Events(): + if !httpRouteDone { + httpRouteDone = true + wg.Done() + } + case <-tcpRouteSub.Events(): + if !tcpRouteDone { + tcpRouteDone = true + wg.Done() + } + case <-inlineCertSub.Events(): + } + } + }(wg) + + wg.Wait() + + gwNamespaceName := types.NamespacedName{ + Name: k8sGWObj.Name, + Namespace: k8sGWObj.Namespace, + } + + httpRouteNamespaceName := types.NamespacedName{ + Name: httpRouteObj.Name, + Namespace: httpRouteObj.Namespace, + } + + tcpRouteNamespaceName := types.NamespacedName{ + Name: tcpRouteObj.Name, + Namespace: tcpRouteObj.Namespace, + } + + certNamespaceName := types.NamespacedName{ + Name: cert.Name, + Namespace: cert.Namespace, + } + + gwRef := gwCtrl.Translator.ConfigEntryReference(api.APIGateway, gwNamespaceName) + httpRouteRef := gwCtrl.Translator.ConfigEntryReference(api.HTTPRoute, httpRouteNamespaceName) + tcpRouteRef := gwCtrl.Translator.ConfigEntryReference(api.TCPRoute, tcpRouteNamespaceName) + certRef := gwCtrl.Translator.ConfigEntryReference(api.InlineCertificate, certNamespaceName) + + curGWModifyIndex := resourceCache.Get(gwRef).GetModifyIndex() + curHTTPRouteModifyIndex := resourceCache.Get(httpRouteRef).GetModifyIndex() + curTCPRouteModifyIndex := resourceCache.Get(tcpRouteRef).GetModifyIndex() + curCertModifyIndex := resourceCache.Get(certRef).GetModifyIndex() + + err = k8sClient.Get(ctx, gwNamespaceName, k8sGWObj) + require.NoError(t, err) + curGWResourceVersion := k8sGWObj.ResourceVersion + + err = k8sClient.Get(ctx, httpRouteNamespaceName, httpRouteObj) + require.NoError(t, err) + curHTTPRouteResourceVersion := httpRouteObj.ResourceVersion + + err = k8sClient.Get(ctx, tcpRouteNamespaceName, tcpRouteObj) + require.NoError(t, err) + curTCPRouteResourceVersion := tcpRouteObj.ResourceVersion + + err = k8sClient.Get(ctx, certNamespaceName, cert) + require.NoError(t, err) + curCertResourceVersion := cert.ResourceVersion + + go func() { + // reconcile multiple times with no changes to be sure + for i := 0; i < 5; i++ { + _, err = gwCtrl.Reconcile(ctx, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: k8sGWObj.Namespace, + }, + }) + require.NoError(t, err) + } + }() + + require.Never(t, func() bool { + err = k8sClient.Get(ctx, gwNamespaceName, k8sGWObj) + require.NoError(t, err) + newGWResourceVersion := k8sGWObj.ResourceVersion + + err = k8sClient.Get(ctx, httpRouteNamespaceName, httpRouteObj) + require.NoError(t, err) + newHTTPRouteResourceVersion := httpRouteObj.ResourceVersion + + err = k8sClient.Get(ctx, tcpRouteNamespaceName, tcpRouteObj) + require.NoError(t, err) + newTCPRouteResourceVersion := tcpRouteObj.ResourceVersion + + err = k8sClient.Get(ctx, certNamespaceName, cert) + require.NoError(t, err) + newCertResourceVersion := cert.ResourceVersion + + return curGWModifyIndex == resourceCache.Get(gwRef).GetModifyIndex() && + curGWResourceVersion == newGWResourceVersion && + curHTTPRouteModifyIndex == resourceCache.Get(httpRouteRef).GetModifyIndex() && + curHTTPRouteResourceVersion == newHTTPRouteResourceVersion && + curTCPRouteModifyIndex == resourceCache.Get(tcpRouteRef).GetModifyIndex() && + curTCPRouteResourceVersion == newTCPRouteResourceVersion && + curCertModifyIndex == resourceCache.Get(certRef).GetModifyIndex() && + curCertResourceVersion == newCertResourceVersion + }, time.Duration(2*time.Second), time.Duration(500*time.Millisecond), fmt.Sprintf("curGWModifyIndex: %d, newIndx: %d", curGWModifyIndex, resourceCache.Get(gwRef).GetModifyIndex()), + ) + }) + } +} + +func createAllFieldsSetAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { + // listener one configuration + listenerOneName := "listener-one" + listenerOneHostname := "*.consul.io" + listenerOnePort := 3366 + listenerOneProtocol := "https" + + // listener two configuration + listenerTwoName := "listener-two" + listenerTwoHostname := "*.consul.io" + listenerTwoPort := 5432 + listenerTwoProtocol := "http" + + // listener three configuration + listenerThreeName := "listener-three" + listenerThreePort := 8081 + listenerThreeProtocol := "tcp" + + // listener four configuration + listenerFourName := "listener-four" + listenerFourHostname := "*.consul.io" + listenerFourPort := 5433 + listenerFourProtocol := "http" + + // Write gw to k8s + gwClassCfg := &v1alpha1.GatewayClassConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClassConfig", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gateway-class-config", + }, + Spec: v1alpha1.GatewayClassConfigSpec{}, + } + gwClass := &gwv1beta1.GatewayClass{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClass", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gatewayclass", + }, + Spec: gwv1beta1.GatewayClassSpec{ + ControllerName: "consul.hashicorp.com/gateway-controller", + ParametersRef: &gwv1beta1.ParametersReference{ + Group: "consul.hashicorp.com", + Kind: "GatewayClassConfig", + Name: "gateway-class-config", + }, + Description: new(string), + }, + } + gw := &gwv1beta1.Gateway{ + TypeMeta: metav1.TypeMeta{ + Kind: "Gateway", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gw", + Namespace: namespace, + Annotations: make(map[string]string), + }, + Spec: gwv1beta1.GatewaySpec{ + GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), + Listeners: []gwv1beta1.Listener{ + { + Name: gwv1beta1.SectionName(listenerOneName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), + Port: gwv1beta1.PortNumber(listenerOnePort), + Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), + TLS: &gwv1beta1.GatewayTLSConfig{ + CertificateRefs: []gwv1beta1.SecretObjectReference{ + { + Kind: common.PointerTo(gwv1beta1.Kind("Secret")), + Name: gwv1beta1.ObjectName("one-cert"), + Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), + }, + }, + }, + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerTwoName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerTwoHostname)), + Port: gwv1beta1.PortNumber(listenerTwoPort), + Protocol: gwv1beta1.ProtocolType(listenerTwoProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("Same")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerThreeName), + Port: gwv1beta1.PortNumber(listenerThreePort), + Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerFourName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerFourHostname)), + Port: gwv1beta1.PortNumber(listenerFourPort), + Protocol: gwv1beta1.ProtocolType(listenerFourProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("Selector")), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.NamespaceNameLabel: "consul", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, gwClassCfg) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gwClass) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gw) + require.NoError(t, err) + + return gw +} + +func createAllFieldsSetHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { + svcDefault := &v1alpha1.ServiceDefaults{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceDefaults", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + Spec: v1alpha1.ServiceDefaultsSpec{ + Protocol: "http", + }, + } + + svc := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "high", + Protocol: "TCP", + Port: 8080, + }, + }, + Selector: map[string]string{"app": "Service"}, + }, + } + + serviceAccount := &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceAccount", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + } + + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: common.PointerTo(int32(1)), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "Service"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{}, + }, + }, + } + + err := k8sClient.Create(ctx, svcDefault) + require.NoError(t, err) + + err = k8sClient.Create(ctx, svc) + require.NoError(t, err) + + err = k8sClient.Create(ctx, serviceAccount) + require.NoError(t, err) + + err = k8sClient.Create(ctx, deployment) + require.NoError(t, err) + + route := &gwv1beta1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "HTTPRoute", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "http-route", + }, + Spec: gwv1beta1.HTTPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Kind: (*gwv1beta1.Kind)(&gw.Kind), + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[0].Name, + Port: &gw.Spec.Listeners[0].Port, + }, + }, + }, + Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, + Rules: []gwv1beta1.HTTPRouteRule{ + { + Matches: []gwv1beta1.HTTPRouteMatch{ + { + Path: &gwv1beta1.HTTPPathMatch{ + Type: common.PointerTo(gwv1beta1.PathMatchType("PathPrefix")), + Value: common.PointerTo("/v1"), + }, + Headers: []gwv1beta1.HTTPHeaderMatch{ + { + Type: common.PointerTo(gwv1beta1.HeaderMatchExact), + Name: "version", + Value: "version", + }, + }, + QueryParams: []gwv1beta1.HTTPQueryParamMatch{ + { + Type: common.PointerTo(gwv1beta1.QueryParamMatchExact), + Name: "search", + Value: "q", + }, + }, + Method: common.PointerTo(gwv1beta1.HTTPMethod("GET")), + }, + }, + Filters: []gwv1beta1.HTTPRouteFilter{ + { + Type: gwv1beta1.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gwv1beta1.HTTPHeaderFilter{ + Set: []gwv1beta1.HTTPHeader{ + { + Name: "foo", + Value: "bax", + }, + }, + Add: []gwv1beta1.HTTPHeader{ + { + Name: "arc", + Value: "reactor", + }, + }, + Remove: []string{"remove"}, + }, + }, + { + Type: gwv1beta1.HTTPRouteFilterURLRewrite, + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ + Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), + Path: &gwv1beta1.HTTPPathModifier{ + Type: gwv1beta1.FullPathHTTPPathModifier, + ReplaceFullPath: common.PointerTo("/foobar"), + }, + }, + }, + + { + Type: gwv1beta1.HTTPRouteFilterURLRewrite, + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ + Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), + Path: &gwv1beta1.HTTPPathModifier{ + Type: gwv1beta1.PrefixMatchHTTPPathModifier, + ReplacePrefixMatch: common.PointerTo("/foo"), + }, + }, + }, + }, + BackendRefs: []gwv1beta1.HTTPBackendRef{ + { + BackendRef: gwv1beta1.BackendRef{ + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(8080)), + }, + Weight: common.PointerTo(int32(50)), + }, + }, + }, + }, + }, + }, + } + + err = k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func createAllFieldsSetTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { + route := &v1alpha2.TCPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "TCPRoute", + APIVersion: "gateway.networking.k8s.io/v1alpha2", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "tcp-route", + }, + Spec: gwv1alpha2.TCPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Kind: (*gwv1beta1.Kind)(&gw.Kind), + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[2].Name, + Port: &gw.Spec.Listeners[2].Port, + }, + }, + }, + Rules: []gwv1alpha2.TCPRouteRule{ + { + BackendRefs: []gwv1beta1.BackendRef{ + { + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(25000)), + }, + Weight: common.PointerTo(int32(50)), + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func createCert(t *testing.T, ctx context.Context, k8sClient client.WithWatch, certNS string) *corev1.Secret { + // listener one tls config + certName := "one-cert" + + privateKey, err := rsa.GenerateKey(rand.Reader, 1024) + require.NoError(t, err) + + usage := x509.KeyUsageCertSign + expiration := time.Now().AddDate(10, 0, 0) + + cert := &x509.Certificate{ + SerialNumber: big.NewInt(1), + Subject: pkix.Name{ + CommonName: "consul.test", + }, + IsCA: true, + NotBefore: time.Now().Add(-10 * time.Minute), + NotAfter: expiration, + SubjectKeyId: []byte{1, 2, 3, 4, 6}, + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, + KeyUsage: usage, + BasicConstraintsValid: true, + } + caCert := cert + caPrivateKey := privateKey + + data, err := x509.CreateCertificate(rand.Reader, cert, caCert, &privateKey.PublicKey, caPrivateKey) + require.NoError(t, err) + + certBytes := pem.EncodeToMemory(&pem.Block{ + Type: "CERTIFICATE", + Bytes: data, + }) + + privateKeyBytes := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(privateKey), + }) + + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: certNS, + Name: certName, + }, + Data: map[string][]byte{ + corev1.TLSCertKey: certBytes, + corev1.TLSPrivateKeyKey: privateKeyBytes, + }, + } + + err = k8sClient.Create(ctx, secret) + require.NoError(t, err) + + return secret +} + +func minimalFieldsSetAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { + // listener one configuration + listenerOneName := "listener-one" + listenerOneHostname := "*.consul.io" + listenerOnePort := 3366 + listenerOneProtocol := "https" + + // listener three configuration + listenerThreeName := "listener-three" + listenerThreePort := 8081 + listenerThreeProtocol := "tcp" + + // Write gw to k8s + gwClassCfg := &v1alpha1.GatewayClassConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClassConfig", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gateway-class-config", + }, + Spec: v1alpha1.GatewayClassConfigSpec{}, + } + gwClass := &gwv1beta1.GatewayClass{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClass", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gatewayclass", + }, + Spec: gwv1beta1.GatewayClassSpec{ + ControllerName: "consul.hashicorp.com/gateway-controller", + ParametersRef: &gwv1beta1.ParametersReference{ + Group: "consul.hashicorp.com", + Kind: "GatewayClassConfig", + Name: "gateway-class-config", + }, + Description: new(string), + }, + } + gw := &gwv1beta1.Gateway{ + TypeMeta: metav1.TypeMeta{ + Kind: "Gateway", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gw", + Annotations: make(map[string]string), + }, + Spec: gwv1beta1.GatewaySpec{ + GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), + Listeners: []gwv1beta1.Listener{ + { + Name: gwv1beta1.SectionName(listenerOneName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), + Port: gwv1beta1.PortNumber(listenerOnePort), + Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), + TLS: &gwv1beta1.GatewayTLSConfig{ + CertificateRefs: []gwv1beta1.SecretObjectReference{ + { + Kind: common.PointerTo(gwv1beta1.Kind("Secret")), + Name: gwv1beta1.ObjectName("one-cert"), + Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), + }, + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerThreeName), + Port: gwv1beta1.PortNumber(listenerThreePort), + Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, gwClassCfg) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gwClass) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gw) + require.NoError(t, err) + + return gw +} + +func minimalFieldsSetHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { + svcDefault := &v1alpha1.ServiceDefaults{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceDefaults", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + Spec: v1alpha1.ServiceDefaultsSpec{ + Protocol: "http", + }, + } + + svc := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "high", + Protocol: "TCP", + Port: 8080, + }, + }, + Selector: map[string]string{"app": "Service"}, + }, + } + + serviceAccount := &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceAccount", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + } + + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: common.PointerTo(int32(1)), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "Service"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{}, + }, + }, + } + + err := k8sClient.Create(ctx, svcDefault) + require.NoError(t, err) + + err = k8sClient.Create(ctx, svc) + require.NoError(t, err) + + err = k8sClient.Create(ctx, serviceAccount) + require.NoError(t, err) + + err = k8sClient.Create(ctx, deployment) + require.NoError(t, err) + + route := &gwv1beta1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "HTTPRoute", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "http-route", + }, + Spec: gwv1beta1.HTTPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Kind: (*gwv1beta1.Kind)(&gw.Kind), + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[0].Name, + Port: &gw.Spec.Listeners[0].Port, + }, + }, + }, + Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, + Rules: []gwv1beta1.HTTPRouteRule{ + { + BackendRefs: []gwv1beta1.HTTPBackendRef{ + { + BackendRef: gwv1beta1.BackendRef{ + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(8080)), + }, + }, + }, + }, + }, + }, + }, + } + + err = k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func minimalFieldsSetTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { + route := &v1alpha2.TCPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "TCPRoute", + APIVersion: "gateway.networking.k8s.io/v1alpha2", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "tcp-route", + }, + Spec: gwv1alpha2.TCPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Kind: (*gwv1beta1.Kind)(&gw.Kind), + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[1].Name, + Port: &gw.Spec.Listeners[1].Port, + }, + }, + }, + Rules: []gwv1alpha2.TCPRouteRule{ + { + BackendRefs: []gwv1beta1.BackendRef{ + { + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(25000)), + }, + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func createFunkyCasingFieldsAPIGW(t *testing.T, ctx context.Context, k8sClient client.WithWatch, namespace string) *gwv1beta1.Gateway { + // listener one configuration + listenerOneName := "listener-one" + listenerOneHostname := "*.consul.io" + listenerOnePort := 3366 + listenerOneProtocol := "hTtPs" + + // listener two configuration + listenerTwoName := "listener-two" + listenerTwoHostname := "*.consul.io" + listenerTwoPort := 5432 + listenerTwoProtocol := "HTTP" + + // listener three configuration + listenerThreeName := "listener-three" + listenerThreePort := 8081 + listenerThreeProtocol := "tCp" + + // listener four configuration + listenerFourName := "listener-four" + listenerFourHostname := "*.consul.io" + listenerFourPort := 5433 + listenerFourProtocol := "hTTp" + + // Write gw to k8s + gwClassCfg := &v1alpha1.GatewayClassConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClassConfig", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gateway-class-config", + }, + Spec: v1alpha1.GatewayClassConfigSpec{}, + } + gwClass := &gwv1beta1.GatewayClass{ + TypeMeta: metav1.TypeMeta{ + Kind: "GatewayClass", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gatewayclass", + }, + Spec: gwv1beta1.GatewayClassSpec{ + ControllerName: "consul.hashicorp.com/gateway-controller", + ParametersRef: &gwv1beta1.ParametersReference{ + Group: "consul.hashicorp.com", + Kind: "GatewayClassConfig", + Name: "gateway-class-config", + }, + Description: new(string), + }, + } + gw := &gwv1beta1.Gateway{ + TypeMeta: metav1.TypeMeta{ + Kind: "Gateway", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "gw", + Namespace: namespace, + Annotations: make(map[string]string), + }, + Spec: gwv1beta1.GatewaySpec{ + GatewayClassName: gwv1beta1.ObjectName(gwClass.Name), + Listeners: []gwv1beta1.Listener{ + { + Name: gwv1beta1.SectionName(listenerOneName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerOneHostname)), + Port: gwv1beta1.PortNumber(listenerOnePort), + Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), + TLS: &gwv1beta1.GatewayTLSConfig{ + CertificateRefs: []gwv1beta1.SecretObjectReference{ + { + Kind: common.PointerTo(gwv1beta1.Kind("Secret")), + Name: gwv1beta1.ObjectName("one-cert"), + Namespace: common.PointerTo(gwv1beta1.Namespace(namespace)), + }, + }, + }, + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerTwoName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerTwoHostname)), + Port: gwv1beta1.PortNumber(listenerTwoPort), + Protocol: gwv1beta1.ProtocolType(listenerTwoProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("Same")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerThreeName), + Port: gwv1beta1.PortNumber(listenerThreePort), + Protocol: gwv1beta1.ProtocolType(listenerThreeProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("All")), + }, + }, + }, + { + Name: gwv1beta1.SectionName(listenerFourName), + Hostname: common.PointerTo(gwv1beta1.Hostname(listenerFourHostname)), + Port: gwv1beta1.PortNumber(listenerFourPort), + Protocol: gwv1beta1.ProtocolType(listenerFourProtocol), + AllowedRoutes: &gwv1beta1.AllowedRoutes{ + Namespaces: &gwv1beta1.RouteNamespaces{ + From: common.PointerTo(gwv1beta1.FromNamespaces("Selector")), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + common.NamespaceNameLabel: "consul", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, gwClassCfg) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gwClass) + require.NoError(t, err) + + err = k8sClient.Create(ctx, gw) + require.NoError(t, err) + + return gw +} + +func createFunkyCasingFieldsHTTPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *gwv1beta1.HTTPRoute { + svcDefault := &v1alpha1.ServiceDefaults{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceDefaults", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + Spec: v1alpha1.ServiceDefaultsSpec{ + Protocol: "hTtp", + }, + } + + svc := &corev1.Service{ + TypeMeta: metav1.TypeMeta{ + Kind: "Service", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: corev1.ServiceSpec{ + Ports: []corev1.ServicePort{ + { + Name: "high", + Protocol: "TCP", + Port: 8080, + }, + }, + Selector: map[string]string{"app": "Service"}, + }, + } + + serviceAccount := &corev1.ServiceAccount{ + TypeMeta: metav1.TypeMeta{ + Kind: "ServiceAccount", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + }, + } + + deployment := &appsv1.Deployment{ + TypeMeta: metav1.TypeMeta{ + Kind: "Deployment", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "Service", + Labels: map[string]string{"app": "Service"}, + }, + Spec: appsv1.DeploymentSpec{ + Replicas: common.PointerTo(int32(1)), + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "Service"}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{}, + Spec: corev1.PodSpec{}, + }, + }, + } + + err := k8sClient.Create(ctx, svcDefault) + require.NoError(t, err) + + err = k8sClient.Create(ctx, svc) + require.NoError(t, err) + + err = k8sClient.Create(ctx, serviceAccount) + require.NoError(t, err) + + err = k8sClient.Create(ctx, deployment) + require.NoError(t, err) + + route := &gwv1beta1.HTTPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "HTTPRoute", + APIVersion: "gateway.networking.k8s.io/v1beta1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "http-route", + }, + Spec: gwv1beta1.HTTPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[0].Name, + Port: &gw.Spec.Listeners[0].Port, + }, + }, + }, + Hostnames: []gwv1beta1.Hostname{"route.consul.io"}, + Rules: []gwv1beta1.HTTPRouteRule{ + { + Matches: []gwv1beta1.HTTPRouteMatch{ + { + Path: &gwv1beta1.HTTPPathMatch{ + Type: common.PointerTo(gwv1beta1.PathMatchPathPrefix), + }, + Headers: []gwv1beta1.HTTPHeaderMatch{ + { + Type: common.PointerTo(gwv1beta1.HeaderMatchExact), + Name: "version", + Value: "version", + }, + }, + QueryParams: []gwv1beta1.HTTPQueryParamMatch{ + { + Type: common.PointerTo(gwv1beta1.QueryParamMatchExact), + Name: "search", + Value: "q", + }, + }, + Method: common.PointerTo(gwv1beta1.HTTPMethod("geT")), + }, + }, + Filters: []gwv1beta1.HTTPRouteFilter{ + { + Type: gwv1beta1.HTTPRouteFilterRequestHeaderModifier, + RequestHeaderModifier: &gwv1beta1.HTTPHeaderFilter{ + Set: []gwv1beta1.HTTPHeader{ + { + Name: "foo", + Value: "bax", + }, + }, + Add: []gwv1beta1.HTTPHeader{ + { + Name: "arc", + Value: "reactor", + }, + }, + Remove: []string{"remove"}, + }, + }, + { + Type: gwv1beta1.HTTPRouteFilterURLRewrite, + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ + Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), + Path: &gwv1beta1.HTTPPathModifier{ + Type: gwv1beta1.FullPathHTTPPathModifier, + ReplaceFullPath: common.PointerTo("/foobar"), + }, + }, + }, + + { + Type: gwv1beta1.HTTPRouteFilterURLRewrite, + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{ + Hostname: common.PointerTo(gwv1beta1.PreciseHostname("host.com")), + Path: &gwv1beta1.HTTPPathModifier{ + Type: gwv1beta1.PrefixMatchHTTPPathModifier, + ReplacePrefixMatch: common.PointerTo("/foo"), + }, + }, + }, + }, + BackendRefs: []gwv1beta1.HTTPBackendRef{ + { + BackendRef: gwv1beta1.BackendRef{ + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(8080)), + }, + Weight: common.PointerTo(int32(-50)), + }, + }, + }, + }, + }, + }, + } + + err = k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} + +func createFunkyCasingFieldsTCPRoute(t *testing.T, ctx context.Context, k8sClient client.WithWatch, gw *gwv1beta1.Gateway) *v1alpha2.TCPRoute { + route := &v1alpha2.TCPRoute{ + TypeMeta: metav1.TypeMeta{ + Kind: "TCPRoute", + APIVersion: "gateway.networking.k8s.io/v1alpha2", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "tcp-route", + }, + Spec: gwv1alpha2.TCPRouteSpec{ + CommonRouteSpec: gwv1beta1.CommonRouteSpec{ + ParentRefs: []gwv1beta1.ParentReference{ + { + Namespace: (*gwv1beta1.Namespace)(&gw.Namespace), + Name: gwv1beta1.ObjectName(gw.Name), + SectionName: &gw.Spec.Listeners[2].Name, + Port: &gw.Spec.Listeners[2].Port, + }, + }, + }, + Rules: []gwv1alpha2.TCPRouteRule{ + { + BackendRefs: []gwv1beta1.BackendRef{ + { + BackendObjectReference: gwv1beta1.BackendObjectReference{ + Name: "Service", + Port: common.PointerTo(gwv1beta1.PortNumber(25000)), + }, + Weight: common.PointerTo(int32(-50)), + }, + }, + }, + }, + }, + } + + err := k8sClient.Create(ctx, route) + require.NoError(t, err) + + return route +} From e976b88a26c2e0147daf9582b5e95ccf68383317 Mon Sep 17 00:00:00 2001 From: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> Date: Thu, 29 Jun 2023 09:54:04 -0500 Subject: [PATCH 047/120] api-gateway: Fix nil pointer exception panic (#2487) * fix nil pointer exception * add unit test * added changelog * delete changelog --- .../api-gateway/common/translation.go | 14 ++--- .../api-gateway/common/translation_test.go | 54 +++++++++++++++++++ .../gateway_controller_integration_test.go | 2 + 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/control-plane/api-gateway/common/translation.go b/control-plane/api-gateway/common/translation.go index fd69c8601f..55bfb29a2f 100644 --- a/control-plane/api-gateway/common/translation.go +++ b/control-plane/api-gateway/common/translation.go @@ -254,14 +254,16 @@ func (t ResourceTranslator) translateHTTPFilters(filters []gwv1beta1.HTTPRouteFi } for _, filter := range filters { - consulFilter.Remove = append(consulFilter.Remove, filter.RequestHeaderModifier.Remove...) + if filter.RequestHeaderModifier != nil { + consulFilter.Remove = append(consulFilter.Remove, filter.RequestHeaderModifier.Remove...) - for _, toAdd := range filter.RequestHeaderModifier.Add { - consulFilter.Add[string(toAdd.Name)] = toAdd.Value - } + for _, toAdd := range filter.RequestHeaderModifier.Add { + consulFilter.Add[string(toAdd.Name)] = toAdd.Value + } - for _, toSet := range filter.RequestHeaderModifier.Set { - consulFilter.Set[string(toSet.Name)] = toSet.Value + for _, toSet := range filter.RequestHeaderModifier.Set { + consulFilter.Set[string(toSet.Name)] = toSet.Value + } } // we drop any path rewrites that are not prefix matches as we don't support those diff --git a/control-plane/api-gateway/common/translation_test.go b/control-plane/api-gateway/common/translation_test.go index caa3efbcac..20917151f3 100644 --- a/control-plane/api-gateway/common/translation_test.go +++ b/control-plane/api-gateway/common/translation_test.go @@ -1372,3 +1372,57 @@ func generateTestCertificate(t *testing.T, namespace, name string) corev1.Secret }, } } + +func TestResourceTranslator_translateHTTPFilters(t1 *testing.T) { + type fields struct { + EnableConsulNamespaces bool + ConsulDestNamespace string + EnableK8sMirroring bool + MirroringPrefix string + ConsulPartition string + Datacenter string + } + type args struct { + filters []gwv1beta1.HTTPRouteFilter + } + tests := []struct { + name string + fields fields + args args + want api.HTTPFilters + }{ + { + name: "no httproutemodifier set", + fields: fields{}, + args: args{ + filters: []gwv1beta1.HTTPRouteFilter{ + { + URLRewrite: &gwv1beta1.HTTPURLRewriteFilter{}, + }, + }, + }, + want: api.HTTPFilters{ + Headers: []api.HTTPHeaderFilter{ + { + Add: map[string]string{}, + Set: map[string]string{}, + }, + }, + URLRewrite: nil, + }, + }, + } + for _, tt := range tests { + t1.Run(tt.name, func(t1 *testing.T) { + t := ResourceTranslator{ + EnableConsulNamespaces: tt.fields.EnableConsulNamespaces, + ConsulDestNamespace: tt.fields.ConsulDestNamespace, + EnableK8sMirroring: tt.fields.EnableK8sMirroring, + MirroringPrefix: tt.fields.MirroringPrefix, + ConsulPartition: tt.fields.ConsulPartition, + Datacenter: tt.fields.Datacenter, + } + assert.Equalf(t1, tt.want, t.translateHTTPFilters(tt.args.filters), "translateHTTPFilters(%v)", tt.args.filters) + }) + } +} diff --git a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go index b423ae54e7..43f3d7d41d 100644 --- a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go +++ b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go @@ -37,6 +37,8 @@ import ( ) func TestControllerDoesNotInfinitelyReconcile(t *testing.T) { + //TODO @apigatewayteam test is consistently failing on main after merge, fix in a follow up PR + t.Skip() s := runtime.NewScheme() require.NoError(t, clientgoscheme.AddToScheme(s)) require.NoError(t, gwv1alpha2.Install(s)) From 83f050be498c3b93d5248c2a7020c7e45837b352 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Thu, 29 Jun 2023 13:57:20 -0400 Subject: [PATCH 048/120] Use correct length for certificate RSA key for tests (#2490) * Use correct length for certificate RSA key * api-gateway: Fix nil pointer exception panic (#2487) * fix nil pointer exception * add unit test * added changelog * delete changelog * Remove skip for fixed test --------- Co-authored-by: sarahalsmiller <100602640+sarahalsmiller@users.noreply.github.com> --- .../controllers/gateway_controller_integration_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go index 43f3d7d41d..35b3c64652 100644 --- a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go +++ b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go @@ -652,7 +652,7 @@ func createCert(t *testing.T, ctx context.Context, k8sClient client.WithWatch, c // listener one tls config certName := "one-cert" - privateKey, err := rsa.GenerateKey(rand.Reader, 1024) + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) require.NoError(t, err) usage := x509.KeyUsageCertSign From 8fe4fb6aa8f5217a9060f6d52182d5d5272c3300 Mon Sep 17 00:00:00 2001 From: John Maguire Date: Thu, 29 Jun 2023 15:30:27 -0400 Subject: [PATCH 049/120] APIGW: Validate length of RSA Keys (#2478) * Validate length of RSA key for inline certs * Bring key length check functions over from consul * move validation of key length from certificate parsing into validation of cert * Update to use sentinel errors * Add changelog * Addressing PR comments: fixing text in changelog, fixing import blocks, slight refactor of cert validation for readability * Ensure cert is removed from consul if an invalid one is presented * Fix linting issues, added tests for validating keys --- .changelog/2478.txt | 5 + .../api-gateway/binding/binder_test.go | 4 +- control-plane/api-gateway/binding/result.go | 22 ++-- .../api-gateway/binding/validation.go | 22 +++- control-plane/api-gateway/common/secrets.go | 57 +++++++++- .../api-gateway/common/secrets_test.go | 105 ++++++++++++++++++ .../api-gateway/common/translation.go | 14 ++- 7 files changed, 207 insertions(+), 22 deletions(-) create mode 100644 .changelog/2478.txt create mode 100644 control-plane/api-gateway/common/secrets_test.go diff --git a/.changelog/2478.txt b/.changelog/2478.txt new file mode 100644 index 0000000000..ccbbb71ec8 --- /dev/null +++ b/.changelog/2478.txt @@ -0,0 +1,5 @@ +```release-note:bug +api-gateway: fixes bug where envoy will silently reject RSA keys less than 2048 bits in length when not in FIPS mode, and +will reject keys that are not 2048, 3072, or 4096 bits in length in FIPS mode. We now validate +and reject invalid certs earlier. +``` diff --git a/control-plane/api-gateway/binding/binder_test.go b/control-plane/api-gateway/binding/binder_test.go index bb30b98f52..7366d1a164 100644 --- a/control-plane/api-gateway/binding/binder_test.go +++ b/control-plane/api-gateway/binding/binder_test.go @@ -15,7 +15,6 @@ import ( logrtest "github.com/go-logr/logr/testing" "github.com/google/go-cmp/cmp" - "github.com/hashicorp/consul/api" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -26,6 +25,7 @@ import ( "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" + "github.com/hashicorp/consul/api" ) func init() { @@ -2331,7 +2331,7 @@ func controlledBinder(config BinderConfig) BinderConfig { } func generateTestCertificate(t *testing.T, namespace, name string) (*api.InlineCertificateConfigEntry, corev1.Secret) { - privateKey, err := rsa.GenerateKey(rand.Reader, 1024) + privateKey, err := rsa.GenerateKey(rand.Reader, common.MinKeyLength) require.NoError(t, err) usage := x509.KeyUsageCertSign diff --git a/control-plane/api-gateway/binding/result.go b/control-plane/api-gateway/binding/result.go index 3ccb645c32..fd2eaca829 100644 --- a/control-plane/api-gateway/binding/result.go +++ b/control-plane/api-gateway/binding/result.go @@ -218,15 +218,17 @@ var ( // to the ListenerConditionReason given in the spec. If a reason is overloaded and can // be used with two different types of things (i.e. something is not found or it's not supported) // then we distinguish those two usages with errListener*_Usage. - errListenerUnsupportedProtocol = errors.New("listener protocol is unsupported") - errListenerPortUnavailable = errors.New("listener port is unavailable") - errListenerHostnameConflict = errors.New("listener hostname conflicts with another listener") - errListenerProtocolConflict = errors.New("listener protocol conflicts with another listener") - errListenerInvalidCertificateRef_NotFound = errors.New("certificate not found") - errListenerInvalidCertificateRef_NotSupported = errors.New("certificate type is not supported") - errListenerInvalidCertificateRef_InvalidData = errors.New("certificate is invalid or does not contain a supported server name") - errListenerInvalidRouteKinds = errors.New("allowed route kind is invalid") - errListenerProgrammed_Invalid = errors.New("listener cannot be programmed because it is invalid") + errListenerUnsupportedProtocol = errors.New("listener protocol is unsupported") + errListenerPortUnavailable = errors.New("listener port is unavailable") + errListenerHostnameConflict = errors.New("listener hostname conflicts with another listener") + errListenerProtocolConflict = errors.New("listener protocol conflicts with another listener") + errListenerInvalidCertificateRef_NotFound = errors.New("certificate not found") + errListenerInvalidCertificateRef_NotSupported = errors.New("certificate type is not supported") + errListenerInvalidCertificateRef_InvalidData = errors.New("certificate is invalid or does not contain a supported server name") + errListenerInvalidCertificateRef_NonFIPSRSAKeyLen = errors.New("certificate has an invalid length: RSA Keys must be at least 2048-bit") + errListenerInvalidCertificateRef_FIPSRSAKeyLen = errors.New("certificate has an invalid length: RSA keys must be either 2048-bit, 3072-bit, or 4096-bit in FIPS mode") + errListenerInvalidRouteKinds = errors.New("allowed route kind is invalid") + errListenerProgrammed_Invalid = errors.New("listener cannot be programmed because it is invalid") // Below is where any custom generic listener validation errors should go. // We map anything under here to a custom ListenerConditionReason of Invalid on @@ -372,7 +374,7 @@ func (l listenerValidationResult) resolvedRefsCondition(generation int64) metav1 } switch l.refErr { - case errListenerInvalidCertificateRef_NotFound, errListenerInvalidCertificateRef_NotSupported, errListenerInvalidCertificateRef_InvalidData: + case errListenerInvalidCertificateRef_NotFound, errListenerInvalidCertificateRef_NotSupported, errListenerInvalidCertificateRef_InvalidData, errListenerInvalidCertificateRef_NonFIPSRSAKeyLen, errListenerInvalidCertificateRef_FIPSRSAKeyLen: return metav1.Condition{ Type: "ResolvedRefs", Status: metav1.ConditionFalse, diff --git a/control-plane/api-gateway/binding/validation.go b/control-plane/api-gateway/binding/validation.go index 0e17e2b306..a57cf598a4 100644 --- a/control-plane/api-gateway/binding/validation.go +++ b/control-plane/api-gateway/binding/validation.go @@ -6,9 +6,6 @@ package binding import ( "strings" - "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" - "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" - "github.com/hashicorp/consul/api" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" klabels "k8s.io/apimachinery/pkg/labels" @@ -17,6 +14,11 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + + "github.com/hashicorp/consul-k8s/control-plane/api-gateway/common" + "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" + "github.com/hashicorp/consul-k8s/control-plane/version" + "github.com/hashicorp/consul/api" ) var ( @@ -205,10 +207,20 @@ func validateTLS(gateway gwv1beta1.Gateway, tls *gwv1beta1.GatewayTLSConfig, res } func validateCertificateData(secret corev1.Secret) error { - _, _, err := common.ParseCertificateData(secret) + _, privateKey, err := common.ParseCertificateData(secret) if err != nil { return errListenerInvalidCertificateRef_InvalidData } + + err = common.ValidateKeyLength(privateKey) + if err != nil { + if version.IsFIPS() { + return errListenerInvalidCertificateRef_FIPSRSAKeyLen + } + + return errListenerInvalidCertificateRef_NonFIPSRSAKeyLen + } + return nil } @@ -235,7 +247,7 @@ func validateListeners(gateway gwv1beta1.Gateway, listeners []gwv1beta1.Listener _, supported := supportedKindsForProtocol[listener.Protocol] if !supported { result.acceptedErr = errListenerUnsupportedProtocol - } else if listener.Port == 20000 { //admin port + } else if listener.Port == 20000 { // admin port result.acceptedErr = errListenerPortUnavailable } diff --git a/control-plane/api-gateway/common/secrets.go b/control-plane/api-gateway/common/secrets.go index f7e6064d9f..1b7d8dec33 100644 --- a/control-plane/api-gateway/common/secrets.go +++ b/control-plane/api-gateway/common/secrets.go @@ -12,6 +12,14 @@ import ( "github.com/miekg/dns" corev1 "k8s.io/api/core/v1" + + "github.com/hashicorp/consul-k8s/control-plane/version" +) + +var ( + errFailedToParsePrivateKeyPem = errors.New("failed to parse private key PEM") + errKeyLengthTooShort = errors.New("RSA key length must be at least 2048-bit") + errKeyLengthTooShortFIPS = errors.New("RSA key length must be at either 2048-bit, 3072-bit, or 4096-bit in FIPS mode") ) func ParseCertificateData(secret corev1.Secret) (cert string, privateKey string, err error) { @@ -20,7 +28,7 @@ func ParseCertificateData(secret corev1.Secret) (cert string, privateKey string, privateKeyBlock, _ := pem.Decode(decodedPrivateKey) if privateKeyBlock == nil { - return "", "", errors.New("failed to parse private key PEM") + return "", "", errFailedToParsePrivateKeyPem } certificateBlock, _ := pem.Decode(decodedCertificate) @@ -66,3 +74,50 @@ func validateCertificateHosts(certificate *x509.Certificate) error { return nil } + +// Envoy will silently reject any keys that are less than 2048 bytes long +// https://github.com/envoyproxy/envoy/blob/main/source/extensions/transport_sockets/tls/context_impl.cc#L238 +const MinKeyLength = 2048 + +// ValidateKeyLength ensures that the key length for a certificate is of a valid length +// for envoy dependent on if consul is running in FIPS mode or not. +func ValidateKeyLength(privateKey string) error { + privateKeyBlock, _ := pem.Decode([]byte(privateKey)) + + if privateKeyBlock == nil { + return errFailedToParsePrivateKeyPem + } + + if privateKeyBlock.Type != "RSA PRIVATE KEY" { + return nil + } + + key, err := x509.ParsePKCS1PrivateKey(privateKeyBlock.Bytes) + if err != nil { + return err + } + + keyBitLen := key.N.BitLen() + + if version.IsFIPS() { + return fipsLenCheck(keyBitLen) + } + + return nonFipsLenCheck(keyBitLen) +} + +func nonFipsLenCheck(keyLen int) error { + // ensure private key is of the correct length + if keyLen < MinKeyLength { + return errKeyLengthTooShort + } + + return nil +} + +func fipsLenCheck(keyLen int) error { + if keyLen != 2048 && keyLen != 3072 && keyLen != 4096 { + return errKeyLengthTooShortFIPS + } + return nil +} diff --git a/control-plane/api-gateway/common/secrets_test.go b/control-plane/api-gateway/common/secrets_test.go new file mode 100644 index 0000000000..d5a2578b5e --- /dev/null +++ b/control-plane/api-gateway/common/secrets_test.go @@ -0,0 +1,105 @@ +package common + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestValidateKeyLength(t *testing.T) { + tooShortPrivateKey := `-----BEGIN RSA PRIVATE KEY----- +MIICXAIBAAKBgQCtmK1VjmXJ7vm4CZkkOSjc+kjGNMlyce5rXxwlDRz9LcGGc3Tg +kwUJesyBpDtxLLVHXQIPr5mWYbX/W/ezQ9sntxrATbDek8pBgoOlARebwkD2ivVW +BWfVhlryVihWlXApKiJ2n3i0m+OVtdrceC9Bv2hEMhYVOwzxtb3O0YFkbwIDAQAB +AoGAIxgnipFUEKPIRiVimUkY8ruCdNd9Fi7kNT6wEOl6v9A9PHIg4bm3Hfh+WYMb +JUEVkMzDuuoUEavFQE+WXt5L8oE1lEBmN2++FQsvllN+MRBTRg2sfw4mUWDI6S4r +h8+XNTzTIg2sUd2J3o2qNmQoOheYb+iuYDj76IFoEdwwZ0kCQQDYKKs5HAbnrLj1 +UrOp8TyHdFf0YNw5tGdbNTbffq4rlBD6SW70+Sj624i2UqdnYwRiWzdXv3zN08aI +Vfoh2cGlAkEAzZe5B6BhiX/PcIYutMtuT3K+mysFNlowrutXWoQOpR7gGAkgEt6e +oCDgx1QJRjsp6NFQxKc6l034Hzs17gqJgwJAcu9U873aUg9+HTuHOoKB28haCCAE +mU46cr3d2oKCW7uUN3EaZXmid5iJneBfENMOfrnfuHGiC9NiShXlNWCS3QJAO5Ne +w83+1ahaxUGs4SkeExmuECrcPM7P0rBRxOIFmGWlDHIAgFdQYhiE6l34vghA8b1O +CV5oRRYL84jl7M/S3wJBALDfL5YXcc8P6scLJJ1biqhLYppvGN5CUwbsJsluvHCW +XCTVIbPOaS42A0xUfpoiTcdbNSFRvdCzPR5nsGy8Y7g= +-----END RSA PRIVATE KEY-----` + validPrivateKey := `-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAzVKRcYlTHHPjPbCieOFIUT2hCouRYe4N8ZhNrSpZf/BAAn4M +d/LWn/9OrLagbxrRF6cWdWGNEI2COnBRLgNVxyPXneaHaYFqOBRi9GWhuD3sw1jn +7gf4/m/AVO8cu2JYjEX+s9RjSRzpjx+4nhit46bGNUyb9qUeQwoBidAzOSmU8nHY +y3LpuuzkjS3FEyNXHxqgpTJnV4ytx8YGkPnG92GBAlrZnr4Eclv0/Sq6OViTpeuh +z8noNkbugYWHMXGlTZ4lPnELJW2fx/HIpD2ovOO3X8XYBo5KDzs9qyKzDgIOMZLF +i/qLCLHgfosb4TMaXCeVu4fA7Y47jtGOO4mbiwIDAQABAoIBAFhicDibIDtRyaLv +K+l0NPC/4liLPwCUfM0gvmNKJS/VSICqKQzjbK+ANCpWDVb2iMaxRxItdY+IEuS8 +H736cozgaXtP1r+8lXBhmj1RmJ2ajpaC6YgGR5GjonwNWGVzjuGHaf6YcUryVrol +MhBgWE50psMf4M16Q74hCwt7o+k5Lz55xKasgc9dtSnvyCupPBwrOT+d55C1P2Wn +2oebWM4WKtCZIgvlvZrt4xQkGWy9qloxL6V1F67ZbizAyFMZUMmJv+4/whF8tmXi +aydleL64K23ZSK1pM/x0JI+7qo0GpEoA4k+2fdmh5dAOM0TrXhV5Kv01efLIaITT +s7lYjG0CgYEA4qGIM7qO3e9fHgSK/9UdxnpL/1OvfYATBMhEtR46sAxmKQGC8fTM +iTBkmLAKn3zBgDghCbygPIQjex+W+Ra7JkQIcGB6KLR8rr5GkOuF6vkqHV93RQRT +lT/1quqq3fVH6V4ymifKJCDNg0IEPcmo+M8RnXBgpFsCN4b5UyjXNScCgYEA5+4h +LITPJxGytlWzwtsy44U2PvafJYJCktW+LYqhk3xzz4qWX5ubmPz18LrEyybgcy/W +Dm4JCu+TOS2gvf2WbJKR/tKdgRN7dkU/dbgMtRL8QW5ir+5qqRITYOhiSZPIOpbP +5zg+c/ZvmK/t5h35/8l7b0bu/E1FOEF27ADpzP0CgYEArqch2gup0muI+A80N9i7 +q5vQOaL6mVM8VPEp0hLL06Sajnt1uJWZkxhSTkFMzoBMd03KWECflEOZPGep56iW +7fR8NG6Fdh0yAVDt/P0lJWKEDELoHa4p49l4sBFNQOSoWLaZdKe5ZoJJHyCfOCbT +K3wY7SYPtFnWqYhBWM8emv0CgYBdrNqNRp78orNR3c+bNjmZl6ZPTAD/f1swP1Bu +yH12Ol/0RX9y4kC4TANx1Z3Ch9ND8uA8N8lDN3x5Laqs0g29kH2TNLIU/i9xl4qI +G2xWfnKQYutNL7i4zOoyy+lW2m+W6m7Sbu8am0B7pSMrPJRK8a//Q+Em2nbIv/gu +XjgQaQKBgHKZUKkMv597vpAjgTNsKIl5RDFONBq3omnAwlK9EDLVeAxIrvrvMHBW +H/ZMFpSGp1eQgKyu1xkEqGdkYXx7BKtdTHK+Thqif2ZGWczy5rVSAIsBYDo1DGE2 +wbocWxkWNb5o2ZZtis5lTB6nr9EWo0zyaPqIh0pfjqVEES2YDEx6 +-----END RSA PRIVATE KEY-----` + nonTraditionalRSAKey := `-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCcrB9oNKLtzA3Q +02KDgtsnrxns7vJ5aCkjJCm/h0Ju7a2mel5YHSN5iLlU5oTMJVIMpWlW9E8P76/a +GLGMNfSBRVJdfW71iks/ddp4SjpDe9Bo+aY2snrR2/AP7eQepVNjFbg4YLQqvENh +05k1FuuP1/AgGVNn0kGEwzKxz35shmhRKBCvaRaHLz/fdkDIeIrVLON4FnmAmpOZ +AztZCwAZc6HZfj8Nh9Wlaw6Dg2boIgxTU160pwpX+nUxcJ9M5sUP9DBuNL0Mdrqi +U+R49uqG/5ssSk+xVik3q+WF+XySJ6H21fttWDJS2OTm/Nx/wHlBC73mthbA0emB +rkiBy9SBAgMBAAECggEAOhybz6aKcmKYE0d8yGPejwMjPh9JH+ATNh4hQBHXAdc1 +7ESCPvOb52XfvE5+nkwPeXJXNrIKq1IPq3kyTdvrc5F3Ygb3A6tGiuTXYnvBzasc +m/tRfANKjBGkovvte7J90ghJ2tt/qERJR/1Y2/jC6glB314VcjJqK+jNImfgsDa7 +1r47efKG7B5eUGvhQDTpL5ENXKxIdvCghHrLqj19QGUZ5MbXsEYrso0lxKw2Xk39 +uM8p3WTxIy0LQGyCm+FYlJ7r61tm7tUOGuNT0YiptVavIw1QPgIbRWdS2gnJu3+J +kHS0vu6AW1fJav48TA9hXcIQR70alrJA2VVqsvQouwKBgQDNs96l8BfWD6s/urIw +yzC3/VZPLFJ3BlxvkdP1UDC0S+7pgQ6qdEmJg0z5IfYzDB1PK2X/DS/70JA1LRSS +MRmjQGHCYIp9g8EqmABwfKf4YnN53KPRyR8Yq1pwaq7wKowtW+5GH95qQPINZsNO +J21AENEzq7IoB4gpM3tIaX73YwKBgQDC+yl5JvoV7e6FIpFrwL62aKrWmpidML/G +stdrg9ylCSM9SIVFINMhmFPicW1+DrkQ5HRV7DG//ZcOZNbbNmSu32PVcQI1MJgQ +rkMZ3ukUURnlvQYOEmZY4zHzTJ+jcw6kEH/+b47Bv13PpD7ZqA4/28dpU9wi9gt3 ++GiSnkKDywKBgHqjr63dPEjapK3lQFHJAu3fM7MWaMAf4cJ+/hD202LbFsDOuhC0 +Lhe3WY/7SI7cvSizZicvFJmcmi2qB+a1MWTcgKxj5I26nNMpNrHaEEcNY22XN3Be +6ZRKrSvy3wO/Sj3M3n2eiHtu5yFIUE7rQL5+iEu3JQuqmep+kBT3GMSjAoGAP77B +VlyJ0nWRT3F3vZSsRRJ/F94/GtT/PcTmbL4Vetc78CMvfuQ2YntcoWGX/Ghv1Lf7 +2MN5mF0d75TEMbLcw9dA2l0x7ZXPgVSXl3OrG/tPzi44No2JbHIKuJJKdrN9C+Jh +Fhv+vhUEZIg8DAjHb9U4opTKGZv7L+PEvHqFIHUCgYBTB2TxTgEMNZSsRwrhQRMh +tsz5rS2MoTgzk4BlSsv6xVC4GnBJ2HlNAjYEsBEg50zCCTPlZXcsNjrAxFrwWhLJ +DjN2iMsYFz4WHS94W5UYl6/35ye25KsHuS9vnNeidhFAvYgC1nIkh4mFhLoSeSCG +GODy2KwC2ssLuUHb6WoJ6A== +-----END PRIVATE KEY-----` + + testCases := map[string]struct { + key string + expectedError error + }{ + "key is RSA and of the correct length": { + key: validPrivateKey, + expectedError: nil, + }, + "key is RSA and too short": { + key: tooShortPrivateKey, + expectedError: errKeyLengthTooShort, + }, + "key is non-traditional RSA key": { + key: nonTraditionalRSAKey, + expectedError: nil, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + err := ValidateKeyLength(tc.key) + require.ErrorIs(t, err, tc.expectedError) + }) + } +} diff --git a/control-plane/api-gateway/common/translation.go b/control-plane/api-gateway/common/translation.go index 55bfb29a2f..94241eed22 100644 --- a/control-plane/api-gateway/common/translation.go +++ b/control-plane/api-gateway/common/translation.go @@ -6,14 +6,15 @@ package common import ( "strings" - "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" - "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" - "github.com/hashicorp/consul-k8s/control-plane/namespaces" - "github.com/hashicorp/consul/api" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" + + "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" + "github.com/hashicorp/consul-k8s/control-plane/namespaces" + "github.com/hashicorp/consul/api" ) // ResourceTranslator handles translating K8s resources into Consul config entries. @@ -340,6 +341,11 @@ func (t ResourceTranslator) ToInlineCertificate(secret corev1.Secret) (*api.Inli return nil, err } + err = ValidateKeyLength(privateKey) + if err != nil { + return nil, err + } + namespace := t.Namespace(secret.Namespace) return &api.InlineCertificateConfigEntry{ From ced0ae836a6588c0c5b09f4016f07bc8704bb2fd Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Thu, 29 Jun 2023 13:07:23 -0700 Subject: [PATCH 050/120] add changelog for 1.2.0 dataplane and consul 1.16.0 (#2496) * add changelog for Consul 1.16.0 * add changelog for dataplane 1.2.0 --- .changelog/2476.txt | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changelog/2476.txt diff --git a/.changelog/2476.txt b/.changelog/2476.txt new file mode 100644 index 0000000000..e57889cabe --- /dev/null +++ b/.changelog/2476.txt @@ -0,0 +1,7 @@ +```release-note:improvement +helm: update `imageConsulDataplane` value to `hashicorp/consul-dataplane:1.2.0` +``` + +```release-note:improvement +helm: update `image` value to `hashicorp/consul:1.16.0` +``` \ No newline at end of file From 736649d9d81334df1bddbfd8e4d04d66b719577b Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Fri, 30 Jun 2023 14:02:16 -0400 Subject: [PATCH 051/120] Adds chanelog values for 0.49.7 (#2501) --- CHANGELOG.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cf1d2084f..445e0f1816 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +## 0.49.7 (June 28, 2023) +BREAKING CHANGES: + +* control-plane: All policies managed by consul-k8s will now be updated on upgrade. If you previously edited the policies after install, your changes will be overwritten. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] + +SECURITY: + +* Bump Dockerfile base image for RedHat UBI `consul-k8s-control-plane` image to `ubi-minimal:9.2`. [[GH-2204](https://github.com/hashicorp/consul-k8s/issues/2204)] +* Bump Dockerfile base image to `alpine:3.18`. Resolves [CVE-2023-2650](https://github.com/advisories/GHSA-gqxg-9vfr-p9cg) vulnerability in openssl@3.0.8-r4 [[GH-2284](https://github.com/hashicorp/consul-k8s/issues/2284)] + +FEATURES: + +* helm: Adds `acls.resources` field which can be configured to override the `resource` settings for the `server-acl-init` and `server-acl-init-cleanup` Jobs. [[GH-2416](https://github.com/hashicorp/consul-k8s/issues/2416)] + +IMPROVEMENTS: + +* (Consul Enterprise) Add support to provide inputs via helm for audit log related configuration [[GH-2265](https://github.com/hashicorp/consul-k8s/issues/2265)] +* helm: Update the default amount of memory used by the connect-inject controller so that its less likely to get OOM killed. [[GH-2249](https://github.com/hashicorp/consul-k8s/issues/2249)] + +BUG FIXES: + +* control-plane: Always update ACL policies upon upgrade. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] +* crd: fix bug on service intentions CRD causing some updates to be ignored. [[GH-2194](https://github.com/hashicorp/consul-k8s/issues/2194)] + ## 1.1.2 (June 5, 2023) SECURITY: From 30e9f55ff36085dfa35df822b1055f6a9d6f6d36 Mon Sep 17 00:00:00 2001 From: Nitya Dhanushkodi Date: Mon, 3 Jul 2023 10:36:25 -0700 Subject: [PATCH 052/120] ci: fix eks terraform quota error by cleaning up oidc providers (#2470) cleans up oidc providers older than 8 hours. --- hack/aws-acceptance-test-cleanup/main.go | 125 +++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/hack/aws-acceptance-test-cleanup/main.go b/hack/aws-acceptance-test-cleanup/main.go index d62e5e4405..e4094ec47e 100644 --- a/hack/aws-acceptance-test-cleanup/main.go +++ b/hack/aws-acceptance-test-cleanup/main.go @@ -25,6 +25,7 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/eks" "github.com/aws/aws-sdk-go/service/elb" + "github.com/aws/aws-sdk-go/service/iam" "github.com/cenkalti/backoff/v4" ) @@ -38,6 +39,11 @@ var ( errNotDestroyed = errors.New("not yet destroyed") ) +type oidc struct { + arn string + buildUrl string +} + func main() { flag.BoolVar(&flagAutoApprove, "auto-approve", false, "Skip interactive approval before destroying.") flag.Parse() @@ -68,6 +74,106 @@ func realMain(ctx context.Context) error { eksClient := eks.New(clientSession, awsCfg) ec2Client := ec2.New(clientSession, awsCfg) elbClient := elb.New(clientSession, awsCfg) + iamClient := iam.New(clientSession, awsCfg) + + // Find OIDC providers to delete. + oidcProvidersOutput, err := iamClient.ListOpenIDConnectProvidersWithContext(ctx, &iam.ListOpenIDConnectProvidersInput{}) + if err != nil { + return err + } else if oidcProvidersOutput == nil { + return fmt.Errorf("nil output for OIDC Providers") + } + + toDeleteOidcArns := []*oidc{} + for _, providerEntry := range oidcProvidersOutput.OpenIDConnectProviderList { + arnString := "" + if providerEntry.Arn != nil { + arnString = *providerEntry.Arn + } + // Check if it's older than 8 hours. + older, err := oidcOlderThanEightHours(ctx, iamClient, providerEntry.Arn) + if err != nil { + return err + } + // Only add to delete list if it's older than 8 hours and has a buildURL tag. + if older { + output, err := iamClient.ListOpenIDConnectProviderTags(&iam.ListOpenIDConnectProviderTagsInput{OpenIDConnectProviderArn: providerEntry.Arn}) + if err != nil { + return err + } + for _, tag := range output.Tags { + if tag.Key != nil && *tag.Key == buildURLTag { + var buildUrl string + if tag.Value != nil { + buildUrl = *tag.Value + } + toDeleteOidcArns = append(toDeleteOidcArns, &oidc{arn: arnString, buildUrl: buildUrl}) + } + } + } else { + fmt.Printf("Skipping OIDC provider: %s because it's not over 8 hours old\n", arnString) + } + } + + oidcProvidersExist := true + if len(toDeleteOidcArns) == 0 { + fmt.Println("Found no OIDC Providers to clean up") + oidcProvidersExist = false + } else { + // Print out the OIDC Provider arns and the build tags. + var oidcPrint string + for _, oidcProvider := range toDeleteOidcArns { + oidcPrint += fmt.Sprintf("- %s (%s)\n", oidcProvider.arn, oidcProvider.buildUrl) + } + + fmt.Printf("Found OIDC Providers:\n%s", oidcPrint) + } + + // Check for approval. + if !flagAutoApprove && oidcProvidersExist { + type input struct { + text string + err error + } + inputCh := make(chan input) + + // Read input in a goroutine so we can also exit if we get a Ctrl-C + // (see select{} below). + go func() { + reader := bufio.NewReader(os.Stdin) + fmt.Println("\nDo you want to delete these OIDC Providers (y/n)?") + inputStr, err := reader.ReadString('\n') + if err != nil { + inputCh <- input{err: err} + return + } + inputCh <- input{text: inputStr} + }() + + select { + case in := <-inputCh: + if in.err != nil { + return in.err + } + inputTrimmed := strings.TrimSpace(in.text) + if inputTrimmed != "y" && inputTrimmed != "yes" { + return errors.New("exiting after negative") + } + case <-ctx.Done(): + return errors.New("context cancelled") + } + } + + // Actually delete the OIDC providers. + for _, oidcArn := range toDeleteOidcArns { + fmt.Printf("Deleting OIDC provider: %s\n", oidcArn.arn) + _, err := iamClient.DeleteOpenIDConnectProviderWithContext(ctx, &iam.DeleteOpenIDConnectProviderInput{ + OpenIDConnectProviderArn: &oidcArn.arn, + }) + if err != nil { + return err + } + } // Find VPCs to delete. Most resources we create belong to a VPC, except // for IAM resources, and so if there are no VPCs, that means all leftover resources have been deleted. @@ -537,6 +643,25 @@ func realMain(ctx context.Context) error { return nil } +// oidcOlderThanEightHours checks if the oidc provider is older than 8 hours. +func oidcOlderThanEightHours(ctx context.Context, iamClient *iam.IAM, oidcArn *string) (bool, error) { + fullOidc, err := iamClient.GetOpenIDConnectProviderWithContext(ctx, &iam.GetOpenIDConnectProviderInput{ + OpenIDConnectProviderArn: oidcArn, + }) + if err != nil { + return false, err + } + if fullOidc != nil { + if fullOidc.CreateDate != nil { + d := time.Since(*fullOidc.CreateDate) + if d.Hours() > 8 { + return true, nil + } + } + } + return false, nil +} + func vpcNameAndBuildURL(vpc *ec2.Vpc) (string, string) { var vpcName string var buildURL string From 1161322e494509ca2642811d88c92b898bb7a4d4 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Thu, 6 Jul 2023 12:18:33 -0400 Subject: [PATCH 053/120] build: update versions to 1.3.0-dev (#2511) --- charts/consul/Chart.yaml | 12 ++++++------ charts/consul/values.yaml | 4 ++-- cli/version/version.go | 2 +- control-plane/version/version.go | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/charts/consul/Chart.yaml b/charts/consul/Chart.yaml index 64d7ed4ed0..de8e6e9df6 100644 --- a/charts/consul/Chart.yaml +++ b/charts/consul/Chart.yaml @@ -3,8 +3,8 @@ apiVersion: v2 name: consul -version: 1.2.0-dev -appVersion: 1.16-dev +version: 1.3.0-dev +appVersion: 1.17-dev kubeVersion: ">=1.22.0-0" description: Official HashiCorp Consul Chart home: https://www.consul.io @@ -16,13 +16,13 @@ annotations: artifacthub.io/prerelease: true artifacthub.io/images: | - name: consul - image: docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.16-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.17-dev - name: consul-k8s-control-plane - image: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.2.0-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.3.0-dev - name: consul-dataplane - image: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.2-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.3-dev - name: envoy - image: envoyproxy/envoy:v1.25.1 + image: envoyproxy/envoy:v1.26.2 artifacthub.io/license: MPL-2.0 artifacthub.io/links: | - name: Documentation diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index ad1f829399..6d8eca9d0d 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -66,7 +66,7 @@ global: # image: "hashicorp/consul-enterprise:1.10.0-ent" # ``` # @default: hashicorp/consul: - image: docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.16-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.17-dev # Array of objects containing image pull secret names that will be applied to each service account. # This can be used to reference image pull secrets if using a custom consul or consul-k8s-control-plane Docker image. @@ -86,7 +86,7 @@ global: # image that is used for functionality such as catalog sync. # This can be overridden per component. # @default: hashicorp/consul-k8s-control-plane: - imageK8S: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.2.0-dev + imageK8S: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.3.0-dev # The name of the datacenter that the agents should # register as. This can't be changed once the Consul cluster is up and running diff --git a/cli/version/version.go b/cli/version/version.go index 320600c30b..9cde4a2d66 100644 --- a/cli/version/version.go +++ b/cli/version/version.go @@ -17,7 +17,7 @@ var ( // // Version must conform to the format expected by // github.com/hashicorp/go-version for tests to work. - Version = "1.2.0" + Version = "1.3.0" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release diff --git a/control-plane/version/version.go b/control-plane/version/version.go index 320600c30b..9cde4a2d66 100644 --- a/control-plane/version/version.go +++ b/control-plane/version/version.go @@ -17,7 +17,7 @@ var ( // // Version must conform to the format expected by // github.com/hashicorp/go-version for tests to work. - Version = "1.2.0" + Version = "1.3.0" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release From cbcbdc591901a7e5d4183fe1676a0bb363edbb9b Mon Sep 17 00:00:00 2001 From: "hashicorp-copywrite[bot]" <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Date: Fri, 7 Jul 2023 16:09:44 -0700 Subject: [PATCH 054/120] [COMPLIANCE] Add Copyright and License Headers (#2507) Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> --- control-plane/api-gateway/common/secrets_test.go | 3 +++ .../controllers/gateway_controller_integration_test.go | 3 +++ 2 files changed, 6 insertions(+) diff --git a/control-plane/api-gateway/common/secrets_test.go b/control-plane/api-gateway/common/secrets_test.go index d5a2578b5e..223e8aa24e 100644 --- a/control-plane/api-gateway/common/secrets_test.go +++ b/control-plane/api-gateway/common/secrets_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package common import ( diff --git a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go index 35b3c64652..2605991238 100644 --- a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go +++ b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package controllers import ( From 0cb24d70e70b370599ba4e28addf003240ee2d70 Mon Sep 17 00:00:00 2001 From: David Yu Date: Mon, 10 Jul 2023 08:27:27 -0700 Subject: [PATCH 055/120] values.yaml - replace connect with service mesh for some instances (#2516) * fix connect/service mesh * Update values.yaml --- charts/consul/values.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 6d8eca9d0d..16b641d5cb 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -805,11 +805,11 @@ server: # @type: string storageClass: null - # This will enable/disable [Connect](https://developer.hashicorp.com/consul/docs/connect). Setting this to true + # This will enable/disable [service mesh](https://developer.hashicorp.com/consul/docs/connect). Setting this to true # _will not_ automatically secure pod communication, this # setting will only enable usage of the feature. Consul will automatically initialize - # a new CA and set of certificates. Additional Connect settings can be configured - # by setting the `server.extraConfig` value. + # a new CA and set of certificates. Additional service mesh settings can be configured + # by setting the `server.extraConfig` value or by applying [configuration entries](https://developer.hashicorp.com/consul/docs/connect/config-entries). connect: true serviceAccount: @@ -1611,7 +1611,7 @@ dns: # @type: boolean enabled: "-" - # If true, services using Consul Connect will use Consul DNS + # If true, services using Consul service mesh will use Consul DNS # for default DNS resolution. The DNS lookups fall back to the nameserver IPs # listed in /etc/resolv.conf if not found in Consul. # @type: boolean @@ -2264,7 +2264,7 @@ connectInject: # @type: map meta: null - # Configures metrics for Consul Connect services. All values are overridable + # Configures metrics for Consul service mesh services. All values are overridable # via annotations on a per-pod basis. metrics: # If true, the connect-injector will automatically @@ -2414,7 +2414,7 @@ connectInject: # annotated. Use `["*"]` to automatically allow all k8s namespaces. # # For example, `["namespace1", "namespace2"]` will only allow pods in the k8s - # namespaces `namespace1` and `namespace2` to have Connect sidecars injected + # namespaces `namespace1` and `namespace2` to have Consul service mesh sidecars injected # and registered with Consul. All other k8s namespaces will be ignored. # # To deny all namespaces, set this to `[]`. @@ -2599,7 +2599,7 @@ connectInject: # [Mesh Gateways](https://developer.hashicorp.com/consul/docs/connect/gateways/mesh-gateway) enable Consul Connect to work across Consul datacenters. meshGateway: # If [mesh gateways](https://developer.hashicorp.com/consul/docs/connect/gateways/mesh-gateway) are enabled, a Deployment will be created that runs - # gateways and Consul Connect will be configured to use gateways. + # gateways and Consul service mesh will be configured to use gateways. # This setting is required for [Cluster Peering](https://developer.hashicorp.com/consul/docs/connect/cluster-peering/k8s). # Requirements: consul 1.6.0+ if using `global.acls.manageSystemACLs``. enabled: false From 6624d34b9f1a4d0f12cef156c5f35152ee3e08b5 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Mon, 10 Jul 2023 12:18:38 -0400 Subject: [PATCH 056/120] docs: self service changelog instructions (#2526) --- .github/pull_request_template.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index b615e69dd1..f5d211b137 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,7 +9,6 @@ How I expect reviewers to test this PR: Checklist: - [ ] Tests added -- [ ] CHANGELOG entry added - > HashiCorp engineers only, community PRs should not add a changelog entry. - > Entries should use present tense (e.g. Add support for...) +- [ ] [CHANGELOG entry added](https://github.com/hashicorp/consul-k8s/blob/main/CONTRIBUTING.md#adding-a-changelog-entry) + From 11a18515e988187dfb905a878a53eca04819b60a Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Mon, 10 Jul 2023 13:56:46 -0400 Subject: [PATCH 057/120] feat: adding security context and annotations to tls and acl init/cleanup jobs (#2525) * feat: adding security context and annotations to tls and acl init/cleanup jobs * changelog --------- Co-authored-by: Chinikins --- .changelog/2525.txt | 3 ++ .../consul/templates/gateway-cleanup-job.yaml | 3 ++ .../templates/gateway-resources-job.yaml | 3 ++ .../server-acl-init-cleanup-job.yaml | 7 +++ .../consul/templates/server-acl-init-job.yaml | 7 +++ .../templates/tls-init-cleanup-job.yaml | 7 +++ charts/consul/templates/tls-init-job.yaml | 7 +++ .../consul/test/unit/gateway-cleanup-job.bats | 24 ++++++++- .../test/unit/gateway-resources-job.bats | 25 ++++++++- .../unit/server-acl-init-cleanup-job.bats | 39 ++++++++++++++ .../consul/test/unit/server-acl-init-job.bats | 52 ++++++++++++++++--- .../test/unit/tls-init-cleanup-job.bats | 40 ++++++++++++++ charts/consul/test/unit/tls-init-job.bats | 39 ++++++++++++++ charts/consul/values.yaml | 32 ++++++++++++ 14 files changed, 280 insertions(+), 8 deletions(-) create mode 100644 .changelog/2525.txt diff --git a/.changelog/2525.txt b/.changelog/2525.txt new file mode 100644 index 0000000000..74a2cd596e --- /dev/null +++ b/.changelog/2525.txt @@ -0,0 +1,3 @@ +```release-note:improvement +helm: adds values for `securityContext` and `annotations` on TLS and ACL init/cleanup jobs. +``` diff --git a/charts/consul/templates/gateway-cleanup-job.yaml b/charts/consul/templates/gateway-cleanup-job.yaml index 44f032b5fd..8731aaed81 100644 --- a/charts/consul/templates/gateway-cleanup-job.yaml +++ b/charts/consul/templates/gateway-cleanup-job.yaml @@ -31,6 +31,9 @@ spec: {{- end }} annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.global.acls.annotations }} + {{- tpl .Values.global.acls.annotations . | nindent 8 }} + {{- end }} spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-gateway-cleanup diff --git a/charts/consul/templates/gateway-resources-job.yaml b/charts/consul/templates/gateway-resources-job.yaml index 441e64eb14..5fcd96cad3 100644 --- a/charts/consul/templates/gateway-resources-job.yaml +++ b/charts/consul/templates/gateway-resources-job.yaml @@ -31,6 +31,9 @@ spec: {{- end }} annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.global.acls.annotations }} + {{- tpl .Values.global.acls.annotations . | nindent 8 }} + {{- end }} spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-gateway-resources diff --git a/charts/consul/templates/server-acl-init-cleanup-job.yaml b/charts/consul/templates/server-acl-init-cleanup-job.yaml index 38ecfcf1b0..4d0aa8f05d 100644 --- a/charts/consul/templates/server-acl-init-cleanup-job.yaml +++ b/charts/consul/templates/server-acl-init-cleanup-job.yaml @@ -47,9 +47,16 @@ spec: {{- end }} annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.global.acls.annotations }} + {{- tpl .Values.global.acls.annotations . | nindent 8 }} + {{- end }} spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init-cleanup + {{- if .Values.server.containerSecurityContext.aclInit }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.aclInit | nindent 8 }} + {{- end }} containers: - name: server-acl-init-cleanup image: {{ .Values.global.imageK8S }} diff --git a/charts/consul/templates/server-acl-init-job.yaml b/charts/consul/templates/server-acl-init-job.yaml index 27272d0f76..6625e23b38 100644 --- a/charts/consul/templates/server-acl-init-job.yaml +++ b/charts/consul/templates/server-acl-init-job.yaml @@ -46,6 +46,9 @@ spec: {{- end }} annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.global.acls.annotations }} + {{- tpl .Values.global.acls.annotations . | nindent 8 }} + {{- end }} {{- if .Values.global.secretsBackend.vault.enabled }} {{- /* Run the Vault agent as both an init container and sidecar. @@ -94,6 +97,10 @@ spec: spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-server-acl-init + {{- if .Values.server.containerSecurityContext.aclInit }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.aclInit | nindent 8 }} + {{- end }} {{- if (or .Values.global.tls.enabled .Values.global.acls.replicationToken.secretName .Values.global.acls.bootstrapToken.secretName) }} volumes: {{- if and .Values.global.tls.enabled (not .Values.global.secretsBackend.vault.enabled) }} diff --git a/charts/consul/templates/tls-init-cleanup-job.yaml b/charts/consul/templates/tls-init-cleanup-job.yaml index ba29bb84ae..69b5a30849 100644 --- a/charts/consul/templates/tls-init-cleanup-job.yaml +++ b/charts/consul/templates/tls-init-cleanup-job.yaml @@ -35,9 +35,16 @@ spec: {{- end }} annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.global.tls.annotations }} + {{- tpl .Values.global.tls.annotations . | nindent 8 }} + {{- end }} spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-tls-init-cleanup + {{- if .Values.server.containerSecurityContext.tlsInit }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.tlsInit | nindent 8 }} + {{- end }} containers: - name: tls-init-cleanup image: "{{ .Values.global.image }}" diff --git a/charts/consul/templates/tls-init-job.yaml b/charts/consul/templates/tls-init-job.yaml index d002ae7a75..5839f07dbf 100644 --- a/charts/consul/templates/tls-init-job.yaml +++ b/charts/consul/templates/tls-init-job.yaml @@ -35,9 +35,16 @@ spec: {{- end }} annotations: "consul.hashicorp.com/connect-inject": "false" + {{- if .Values.global.tls.annotations }} + {{- tpl .Values.global.tls.annotations . | nindent 8 }} + {{- end }} spec: restartPolicy: Never serviceAccountName: {{ template "consul.fullname" . }}-tls-init + {{- if .Values.server.containerSecurityContext.tlsInit }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext.tlsInit | nindent 8 }} + {{- end }} {{- if (and .Values.global.tls.caCert.secretName .Values.global.tls.caKey.secretName) }} volumes: - name: consul-ca-cert diff --git a/charts/consul/test/unit/gateway-cleanup-job.bats b/charts/consul/test/unit/gateway-cleanup-job.bats index ff59768c75..657bf4a791 100644 --- a/charts/consul/test/unit/gateway-cleanup-job.bats +++ b/charts/consul/test/unit/gateway-cleanup-job.bats @@ -18,6 +18,28 @@ target=templates/gateway-cleanup-job.yaml assert_empty helm template \ -s $target \ --set 'connectInject.enabled=false' \ - . + . } + +#-------------------------------------------------------------------- +# annotations + +@test "gatewaycleanup/Job: no annotations defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -s $target \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations | del(."consul.hashicorp.com/connect-inject") | del(."consul.hashicorp.com/config-checksum")' | tee /dev/stderr) + [ "${actual}" = "{}" ] +} + +@test "gatewaycleanup/Job: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -s $target \ + --set 'global.acls.annotations=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/charts/consul/test/unit/gateway-resources-job.bats b/charts/consul/test/unit/gateway-resources-job.bats index 0d3bfa2e4d..27bba00ed5 100644 --- a/charts/consul/test/unit/gateway-resources-job.bats +++ b/charts/consul/test/unit/gateway-resources-job.bats @@ -18,7 +18,7 @@ target=templates/gateway-resources-job.yaml assert_empty helm template \ -s $target \ --set 'connectInject.enabled=false' \ - . + . } @test "gatewayresources/Job: imageK8S set properly" { @@ -116,3 +116,26 @@ target=templates/gateway-resources-job.yaml local actual=$(echo "$spec" | jq '.[14]') [ "${actual}" = "\"-service-annotations=- bingo\"" ] } + + +#-------------------------------------------------------------------- +# annotations + +@test "gatewayresources/Job: no annotations defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -s $target \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations | del(."consul.hashicorp.com/connect-inject") | del(."consul.hashicorp.com/config-checksum")' | tee /dev/stderr) + [ "${actual}" = "{}" ] +} + +@test "gatewayresources/Job: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -s $target \ + --set 'global.acls.annotations=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/charts/consul/test/unit/server-acl-init-cleanup-job.bats b/charts/consul/test/unit/server-acl-init-cleanup-job.bats index bf6a455d0e..c886b2ec51 100644 --- a/charts/consul/test/unit/server-acl-init-cleanup-job.bats +++ b/charts/consul/test/unit/server-acl-init-cleanup-job.bats @@ -183,3 +183,42 @@ load _helpers yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) [ "${actual}" = "bar" ] } + +#-------------------------------------------------------------------- +# server.containerSecurityContext.aclInit + +@test "serverACLInitCleanup/Job: securityContext is set when server.containerSecurityContext.aclInit is set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-cleanup-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.containerSecurityContext.aclInit.runAsUser=100' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.securityContext.runAsUser' | tee /dev/stderr) + + [ "${actual}" = "100" ] +} + +#-------------------------------------------------------------------- +# annotations + +@test "serverACLInitCleanup/Job: no annotations defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-cleanup-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations | del(."consul.hashicorp.com/connect-inject") | del(."consul.hashicorp.com/config-checksum")' | tee /dev/stderr) + [ "${actual}" = "{}" ] +} + +@test "serverACLInitCleanup/Job: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-cleanup-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.annotations=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/charts/consul/test/unit/server-acl-init-job.bats b/charts/consul/test/unit/server-acl-init-job.bats index a0d0950e89..17c3e63935 100644 --- a/charts/consul/test/unit/server-acl-init-job.bats +++ b/charts/consul/test/unit/server-acl-init-job.bats @@ -590,6 +590,22 @@ load _helpers [ "${actual}" = "key" ] } +#-------------------------------------------------------------------- +# server.containerSecurityContext.aclInit + +@test "serverACLInit/Job: securityContext is set when server.containerSecurityContext.aclInit is set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'server.containerSecurityContext.aclInit.runAsUser=100' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.securityContext.runAsUser' | tee /dev/stderr) + + [ "${actual}" = "100" ] + +} + #-------------------------------------------------------------------- # Vault @@ -2030,7 +2046,7 @@ load _helpers --set 'global.cloud.authUrl.secretName=auth-url-name' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.authUrl.secretName or global.cloud.authUrl.secretKey is defined, both must be set." ]] } @@ -2050,7 +2066,7 @@ load _helpers --set 'global.cloud.authUrl.secretKey=auth-url-key' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.authUrl.secretName or global.cloud.authUrl.secretKey is defined, both must be set." ]] } @@ -2070,7 +2086,7 @@ load _helpers --set 'global.cloud.apiHost.secretName=auth-url-name' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.apiHost.secretName or global.cloud.apiHost.secretKey is defined, both must be set." ]] } @@ -2090,7 +2106,7 @@ load _helpers --set 'global.cloud.apiHost.secretKey=auth-url-key' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.apiHost.secretName or global.cloud.apiHost.secretKey is defined, both must be set." ]] } @@ -2110,7 +2126,7 @@ load _helpers --set 'global.cloud.scadaAddress.secretName=scada-address-name' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.scadaAddress.secretName or global.cloud.scadaAddress.secretKey is defined, both must be set." ]] } @@ -2130,7 +2146,7 @@ load _helpers --set 'global.cloud.scadaAddress.secretKey=scada-address-key' \ . [ "$status" -eq 1 ] - + [[ "$output" =~ "When either global.cloud.scadaAddress.secretName or global.cloud.scadaAddress.secretKey is defined, both must be set." ]] } @@ -2226,3 +2242,27 @@ load _helpers yq -r '.spec.template.spec.containers[0].resources.foo' | tee /dev/stderr) [ "${actual}" = "bar" ] } + +#-------------------------------------------------------------------- +# annotations + +@test "serverACLInit/Job: no annotations defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations | del(."consul.hashicorp.com/connect-inject") | del(."consul.hashicorp.com/config-checksum")' | tee /dev/stderr) + [ "${actual}" = "{}" ] +} + +@test "serverACLInit/Job: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.annotations=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/charts/consul/test/unit/tls-init-cleanup-job.bats b/charts/consul/test/unit/tls-init-cleanup-job.bats index 04b4a2df31..735d991780 100644 --- a/charts/consul/test/unit/tls-init-cleanup-job.bats +++ b/charts/consul/test/unit/tls-init-cleanup-job.bats @@ -119,3 +119,43 @@ load _helpers [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# server.containerSecurityContext.tlsInit + +@test "tlsInitCleanup/Job: securityContext is set when server.containerSecurityContext.tlsInit is set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/tls-init-cleanup-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.containerSecurityContext.tlsInit.runAsUser=100' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.securityContext.runAsUser' | tee /dev/stderr) + + [ "${actual}" = "100" ] +} + + +#-------------------------------------------------------------------- +# annotations + +@test "tlsInitCleanup/Job: no annotations defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/tls-init-cleanup-job.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations | del(."consul.hashicorp.com/connect-inject") | del(."consul.hashicorp.com/config-checksum")' | tee /dev/stderr) + [ "${actual}" = "{}" ] +} + +@test "tlsInitCleanup/Job: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/tls-init-cleanup-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.annotations=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/charts/consul/test/unit/tls-init-job.bats b/charts/consul/test/unit/tls-init-job.bats index f9294915a5..bf1f84a0a6 100644 --- a/charts/consul/test/unit/tls-init-job.bats +++ b/charts/consul/test/unit/tls-init-job.bats @@ -207,3 +207,42 @@ load _helpers [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# server.containerSecurityContext.tlsInit + +@test "tlsInit/Job: securityContext is set when server.containerSecurityContext.tlsInit is set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'server.containerSecurityContext.tlsInit.runAsUser=100' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.securityContext.runAsUser' | tee /dev/stderr) + + [ "${actual}" = "100" ] +} + +#-------------------------------------------------------------------- +# annotations + +@test "tlsInit/Job: no annotations defined by default" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations | del(."consul.hashicorp.com/connect-inject") | del(."consul.hashicorp.com/config-checksum")' | tee /dev/stderr) + [ "${actual}" = "{}" ] +} + +@test "tlsInit/Job: annotations can be set" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.annotations=foo: bar' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations.foo' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 16b641d5cb..b3f842e429 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -379,6 +379,18 @@ global: # @type: string secretKey: null + # This value defines additional annotations for + # tls init jobs. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + # [Enterprise Only] `enableConsulNamespaces` indicates that you are running # Consul Enterprise v1.7+ with a valid Consul Enterprise license and would # like to make use of configuration beyond registering everything into @@ -489,6 +501,18 @@ global: # @type: string nodeSelector: null + # This value defines additional annotations for + # acl init jobs. This should be formatted as a multi-line string. + # + # ```yaml + # annotations: | + # "sample/annotation1": "foo" + # "sample/annotation2": "bar" + # ``` + # + # @type: string + annotations: null + # [Enterprise Only] This value refers to a Kubernetes or Vault secret that you have created # that contains your enterprise license. It is required if you are using an # enterprise binary. Defining it here applies it to your cluster once a leader @@ -877,6 +901,14 @@ server: # @type: map # @recurse: false server: null + # The acl-init job + # @type: map + # @recurse: false + aclInit: null + # The tls-init job + # @type: map + # @recurse: false + tlsInit: null # This value is used to carefully # control a rolling update of Consul server agents. This value specifies the From fb02159cc1b96fab69e702a30f42724b0bd966fe Mon Sep 17 00:00:00 2001 From: Derek Menteer <105233703+hashi-derek@users.noreply.github.com> Date: Mon, 10 Jul 2023 16:53:01 -0500 Subject: [PATCH 058/120] NET-4813: Fix issue where virtual IP saving had insufficient ACLs. (#2520) Fix issue where virtual IP saving had insufficient ACLs. --- .changelog/2520.txt | 4 +++ .../framework/connhelper/connect_helper.go | 13 +++++++++ .../tests/connect/connect_inject_test.go | 27 +++++++++++++++++++ .../bases/resolver-redirect/intention.yaml | 24 +++++++++++++++++ .../resolver-redirect/kustomization.yaml | 8 ++++++ .../bases/resolver-redirect/resolver.yaml | 10 +++++++ .../bases/resolver-redirect/service.yaml | 15 +++++++++++ .../resolver-redirect/serviceaccount.yaml | 7 +++++ .../kustomization.yaml | 5 ++++ .../subcommand/server-acl-init/rules.go | 1 + .../subcommand/server-acl-init/rules_test.go | 3 +++ 11 files changed, 117 insertions(+) create mode 100644 .changelog/2520.txt create mode 100644 acceptance/tests/fixtures/bases/resolver-redirect/intention.yaml create mode 100644 acceptance/tests/fixtures/bases/resolver-redirect/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/resolver-redirect/resolver.yaml create mode 100644 acceptance/tests/fixtures/bases/resolver-redirect/service.yaml create mode 100644 acceptance/tests/fixtures/bases/resolver-redirect/serviceaccount.yaml create mode 100644 acceptance/tests/fixtures/cases/resolver-redirect-virtualip/kustomization.yaml diff --git a/.changelog/2520.txt b/.changelog/2520.txt new file mode 100644 index 0000000000..96d03dc093 --- /dev/null +++ b/.changelog/2520.txt @@ -0,0 +1,4 @@ +```release-note:bug +transparent-proxy: Fix issue where connect-inject lacked sufficient `mesh:write` privileges in some deployments, +which prevented virtual IPs from persisting properly. +``` diff --git a/acceptance/framework/connhelper/connect_helper.go b/acceptance/framework/connhelper/connect_helper.go index 8695e74d56..d10bf43b1a 100644 --- a/acceptance/framework/connhelper/connect_helper.go +++ b/acceptance/framework/connhelper/connect_helper.go @@ -127,6 +127,19 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { } } +// CreateResolverRedirect creates a resolver that redirects to a static-server, a corresponding k8s service, +// and intentions. This helper is primarly used to ensure that the virtual-ips are persisted to consul properly. +func (c *ConnectHelper) CreateResolverRedirect(t *testing.T) { + logger.Log(t, "creating resolver redirect") + options := c.Ctx.KubectlOptions(t) + kustomizeDir := "../fixtures/cases/resolver-redirect-virtualip" + k8s.KubectlApplyK(t, options, kustomizeDir) + + helpers.Cleanup(t, c.Cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, options, kustomizeDir) + }) +} + // TestConnectionFailureWithoutIntention ensures the connection to the static // server fails when no intentions are configured. func (c *ConnectHelper) TestConnectionFailureWithoutIntention(t *testing.T) { diff --git a/acceptance/tests/connect/connect_inject_test.go b/acceptance/tests/connect/connect_inject_test.go index 3f1660319f..199bbf0f1b 100644 --- a/acceptance/tests/connect/connect_inject_test.go +++ b/acceptance/tests/connect/connect_inject_test.go @@ -60,6 +60,33 @@ func TestConnectInject(t *testing.T) { } } +// TestConnectInject_VirtualIPFailover ensures that KubeDNS entries are saved to the virtual IP address table in Consul. +func TestConnectInject_VirtualIPFailover(t *testing.T) { + cfg := suite.Config() + if !cfg.EnableTransparentProxy { + // This can only be tested in transparent proxy mode. + t.SkipNow() + } + ctx := suite.Environment().DefaultContext(t) + + releaseName := helpers.RandomName() + connHelper := connhelper.ConnectHelper{ + ClusterKind: consul.Helm, + Secure: true, + ReleaseName: releaseName, + Ctx: ctx, + Cfg: cfg, + } + + connHelper.Setup(t) + + connHelper.Install(t) + connHelper.CreateResolverRedirect(t) + connHelper.DeployClientAndServer(t) + + k8s.CheckStaticServerConnectionSuccessful(t, connHelper.Ctx.KubectlOptions(t), "static-client", "http://resolver-redirect") +} + // Test the endpoints controller cleans up force-killed pods. func TestConnectInject_CleanupKilledPods(t *testing.T) { for _, secure := range []bool{false, true} { diff --git a/acceptance/tests/fixtures/bases/resolver-redirect/intention.yaml b/acceptance/tests/fixtures/bases/resolver-redirect/intention.yaml new file mode 100644 index 0000000000..faff0cd251 --- /dev/null +++ b/acceptance/tests/fixtures/bases/resolver-redirect/intention.yaml @@ -0,0 +1,24 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceIntentions +metadata: + name: client-to-server +spec: + destination: + name: static-server + sources: + - name: static-client + action: allow +--- +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceIntentions +metadata: + name: client-to-redirect +spec: + destination: + name: resolver-redirect + sources: + - name: static-client + action: allow \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/resolver-redirect/kustomization.yaml b/acceptance/tests/fixtures/bases/resolver-redirect/kustomization.yaml new file mode 100644 index 0000000000..323957ad53 --- /dev/null +++ b/acceptance/tests/fixtures/bases/resolver-redirect/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - intention.yaml + - service.yaml + - serviceaccount.yaml + - resolver.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/resolver-redirect/resolver.yaml b/acceptance/tests/fixtures/bases/resolver-redirect/resolver.yaml new file mode 100644 index 0000000000..9adbcc9fb4 --- /dev/null +++ b/acceptance/tests/fixtures/bases/resolver-redirect/resolver.yaml @@ -0,0 +1,10 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceResolver +metadata: + name: resolver-redirect +spec: + redirect: + service: static-server \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/resolver-redirect/service.yaml b/acceptance/tests/fixtures/bases/resolver-redirect/service.yaml new file mode 100644 index 0000000000..e63ae97cca --- /dev/null +++ b/acceptance/tests/fixtures/bases/resolver-redirect/service.yaml @@ -0,0 +1,15 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: v1 +kind: Service +metadata: + name: resolver-redirect +spec: + selector: + # Nothing needs to be selected. We only utilize this service so that KubeDNS has a ClusterIP to resolve. + app: idonotexist + ports: + - name: http + port: 80 + targetPort: 8080 diff --git a/acceptance/tests/fixtures/bases/resolver-redirect/serviceaccount.yaml b/acceptance/tests/fixtures/bases/resolver-redirect/serviceaccount.yaml new file mode 100644 index 0000000000..c74ecd667b --- /dev/null +++ b/acceptance/tests/fixtures/bases/resolver-redirect/serviceaccount.yaml @@ -0,0 +1,7 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: resolver-redirect diff --git a/acceptance/tests/fixtures/cases/resolver-redirect-virtualip/kustomization.yaml b/acceptance/tests/fixtures/cases/resolver-redirect-virtualip/kustomization.yaml new file mode 100644 index 0000000000..09790e05c6 --- /dev/null +++ b/acceptance/tests/fixtures/cases/resolver-redirect-virtualip/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../bases/resolver-redirect \ No newline at end of file diff --git a/control-plane/subcommand/server-acl-init/rules.go b/control-plane/subcommand/server-acl-init/rules.go index d86dd38a0a..5f65b6c75c 100644 --- a/control-plane/subcommand/server-acl-init/rules.go +++ b/control-plane/subcommand/server-acl-init/rules.go @@ -330,6 +330,7 @@ partition "{{ .PartitionName }}" { mesh = "write" acl = "write" {{- else }} + mesh = "write" operator = "write" acl = "write" {{- end }} diff --git a/control-plane/subcommand/server-acl-init/rules_test.go b/control-plane/subcommand/server-acl-init/rules_test.go index 1e629d68f7..a45af33c11 100644 --- a/control-plane/subcommand/server-acl-init/rules_test.go +++ b/control-plane/subcommand/server-acl-init/rules_test.go @@ -953,6 +953,7 @@ func TestInjectRules(t *testing.T) { EnablePartitions: false, EnablePeering: false, Expected: ` + mesh = "write" operator = "write" acl = "write" node_prefix "" { @@ -969,6 +970,7 @@ func TestInjectRules(t *testing.T) { EnablePartitions: false, EnablePeering: false, Expected: ` + mesh = "write" operator = "write" acl = "write" node_prefix "" { @@ -987,6 +989,7 @@ func TestInjectRules(t *testing.T) { EnablePartitions: false, EnablePeering: true, Expected: ` + mesh = "write" operator = "write" acl = "write" peering = "write" From 6adb9a2f5ca3c6b86d34334bde49f82e0bca0cd0 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Mon, 10 Jul 2023 16:18:02 -0700 Subject: [PATCH 059/120] reactivate proxy-lifecycle tests (#2532) --- .../tests/connect/connect_proxy_lifecycle_test.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/acceptance/tests/connect/connect_proxy_lifecycle_test.go b/acceptance/tests/connect/connect_proxy_lifecycle_test.go index ecdc51b547..321c002a4c 100644 --- a/acceptance/tests/connect/connect_proxy_lifecycle_test.go +++ b/acceptance/tests/connect/connect_proxy_lifecycle_test.go @@ -17,7 +17,6 @@ import ( "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" "github.com/hashicorp/consul/sdk/testutil/retry" - "github.com/hashicorp/go-version" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -36,15 +35,7 @@ const ( func TestConnectInject_ProxyLifecycleShutdown(t *testing.T) { cfg := suite.Config() - ver, err := version.NewVersion("1.2.0") - require.NoError(t, err) - if cfg.ConsulDataplaneVersion != nil && cfg.ConsulDataplaneVersion.LessThan(ver) { - t.Skipf("skipping this test because proxy lifecycle management is not supported in consul-dataplane version %v", cfg.ConsulDataplaneVersion.String()) - } - for _, testCfg := range []LifecycleShutdownConfig{ - {secure: false, helmValues: map[string]string{}}, - {secure: true, helmValues: map[string]string{}}, {secure: false, helmValues: map[string]string{ helmDrainListenersKey: "true", helmGracePeriodSecondsKey: "15", @@ -72,6 +63,7 @@ func TestConnectInject_ProxyLifecycleShutdown(t *testing.T) { } { // Determine if listeners should be expected to drain inbound connections var drainListenersEnabled bool + var err error val, ok := testCfg.helmValues[helmDrainListenersKey] if ok { drainListenersEnabled, err = strconv.ParseBool(val) From 46766525bed97353e902acc42d338a100a9a47b1 Mon Sep 17 00:00:00 2001 From: Derek Menteer <105233703+hashi-derek@users.noreply.github.com> Date: Mon, 10 Jul 2023 18:27:04 -0500 Subject: [PATCH 060/120] Fix test flakes. (#2483) --- .../framework/connhelper/connect_helper.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/acceptance/framework/connhelper/connect_helper.go b/acceptance/framework/connhelper/connect_helper.go index d10bf43b1a..670307da88 100644 --- a/acceptance/framework/connhelper/connect_helper.go +++ b/acceptance/framework/connhelper/connect_helper.go @@ -117,14 +117,19 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { // Check that both static-server and static-client have been injected and // now have 2 containers. - for _, labelSelector := range []string{"app=static-server", "app=static-client"} { - podList, err := c.Ctx.KubernetesClient(t).CoreV1().Pods(c.Ctx.KubectlOptions(t).Namespace).List(context.Background(), metav1.ListOptions{ - LabelSelector: labelSelector, + retry.RunWith( + &retry.Timer{Timeout: 30 * time.Second, Wait: 100 * time.Millisecond}, t, + func(r *retry.R) { + for _, labelSelector := range []string{"app=static-server", "app=static-client"} { + podList, err := c.Ctx.KubernetesClient(t).CoreV1().Pods(c.Ctx.KubectlOptions(t).Namespace).List(context.Background(), metav1.ListOptions{ + LabelSelector: labelSelector, + FieldSelector: `status.phase=Running`, + }) + require.NoError(r, err) + require.Len(r, podList.Items, 1) + require.Len(r, podList.Items[0].Spec.Containers, 2) + } }) - require.NoError(t, err) - require.Len(t, podList.Items, 1) - require.Len(t, podList.Items[0].Spec.Containers, 2) - } } // CreateResolverRedirect creates a resolver that redirects to a static-server, a corresponding k8s service, From 486061a751d34be9565ff6be0fb9995bd3ae2e64 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Tue, 11 Jul 2023 08:18:21 -0400 Subject: [PATCH 061/120] Update chart to use OSS image (#2528) --- charts/consul/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index b3f842e429..b5f8437d83 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -66,7 +66,7 @@ global: # image: "hashicorp/consul-enterprise:1.10.0-ent" # ``` # @default: hashicorp/consul: - image: docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.17-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul:1.17-dev # Array of objects containing image pull secret names that will be applied to each service account. # This can be used to reference image pull secrets if using a custom consul or consul-k8s-control-plane Docker image. From 6b45156cc14689372ef4eef437aeac281a245b17 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Tue, 11 Jul 2023 10:06:31 -0400 Subject: [PATCH 062/120] Remove todo.txt (#2548) --- charts/consul/todo.txt | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 charts/consul/todo.txt diff --git a/charts/consul/todo.txt b/charts/consul/todo.txt deleted file mode 100644 index c79bef389b..0000000000 --- a/charts/consul/todo.txt +++ /dev/null @@ -1,3 +0,0 @@ - -- [x] Remove gatewayclass gatewayclassconfig bats -- [ ] Add test for each of the CRDs From fd201c57caa59875492914392b6e45a368e3d749 Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Tue, 11 Jul 2023 16:02:26 -0400 Subject: [PATCH 063/120] makes gateway controllers less chatty (#2524) --- .changelog/2524.txt | 3 +++ .../controllers/gateway_controller.go | 25 +++++++++++++++++-- .../controllers/gatewayclass_controller.go | 20 ++++++++++++--- .../gatewayclassconfig_controller.go | 21 +++++++++++----- .../api-gateway/gatekeeper/deployment.go | 8 +++--- .../api-gateway/gatekeeper/gatekeeper.go | 4 +-- .../api-gateway/gatekeeper/service.go | 6 ++--- 7 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 .changelog/2524.txt diff --git a/.changelog/2524.txt b/.changelog/2524.txt new file mode 100644 index 0000000000..5d634e68e1 --- /dev/null +++ b/.changelog/2524.txt @@ -0,0 +1,3 @@ +```release-note:improvement +(api-gateway) make API gateway controller less verbose +``` \ No newline at end of file diff --git a/control-plane/api-gateway/controllers/gateway_controller.go b/control-plane/api-gateway/controllers/gateway_controller.go index 8569508769..66347adea4 100644 --- a/control-plane/api-gateway/controllers/gateway_controller.go +++ b/control-plane/api-gateway/controllers/gateway_controller.go @@ -72,7 +72,7 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct var gateway gwv1beta1.Gateway - log := r.Log.WithValues("gateway", req.NamespacedName) + log := r.Log.V(1).WithValues("gateway", req.NamespacedName) log.Info("Reconciling Gateway") // get the gateway @@ -199,6 +199,11 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct err := r.updateGatekeeperResources(ctx, log, &gateway, updates.GatewayClassConfig) if err != nil { + if k8serrors.IsConflict(err) { + log.Info("error updating object when updating gateway resources, will try to re-reconcile") + + return ctrl.Result{Requeue: true}, nil + } log.Error(err, "unable to update gateway resources") return ctrl.Result{}, err } @@ -206,11 +211,16 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct } else { err := r.deleteGatekeeperResources(ctx, log, &gateway) if err != nil { + if k8serrors.IsConflict(err) { + log.Info("error updating object when deleting gateway resources, will try to re-reconcile") + + return ctrl.Result{Requeue: true}, nil + } log.Error(err, "unable to delete gateway resources") return ctrl.Result{}, err } r.gatewayCache.RemoveSubscription(nonNormalizedConsulKey) - // make sure we have deregister all services even if they haven't + // make sure we have deregistered all services even if they haven't // hit cache yet if err := r.deregisterAllServices(ctx, nonNormalizedConsulKey); err != nil { log.Error(err, "error deregistering services") @@ -266,6 +276,11 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct for _, update := range updates.Kubernetes.Updates.Operations() { log.Info("update in Kubernetes", "kind", update.GetObjectKind().GroupVersionKind().Kind, "namespace", update.GetNamespace(), "name", update.GetName()) if err := r.updateAndResetStatus(ctx, update); err != nil { + if k8serrors.IsConflict(err) { + log.Info("error updating object for gateway, will try to re-reconcile") + + return ctrl.Result{Requeue: true}, nil + } log.Error(err, "error updating object") return ctrl.Result{}, err } @@ -274,6 +289,11 @@ func (r *GatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ct for _, update := range updates.Kubernetes.StatusUpdates.Operations() { log.Info("update status in Kubernetes", "kind", update.GetObjectKind().GroupVersionKind().Kind, "namespace", update.GetNamespace(), "name", update.GetName()) if err := r.Client.Status().Update(ctx, update); err != nil { + if k8serrors.IsConflict(err) { + log.Info("error updating status for gateway, will try to re-reconcile") + + return ctrl.Result{Requeue: true}, nil + } log.Error(err, "error updating status") return ctrl.Result{}, err } @@ -305,6 +325,7 @@ func (r *GatewayController) updateAndResetStatus(ctx context.Context, o client.O if err := r.Client.Update(ctx, o); err != nil { return err } + // reset the status in case it needs to be updated below reflect.ValueOf(o).Elem().FieldByName("Status").Set(status) return nil diff --git a/control-plane/api-gateway/controllers/gatewayclass_controller.go b/control-plane/api-gateway/controllers/gatewayclass_controller.go index e37d1b3bcd..3bde2d6ab1 100644 --- a/control-plane/api-gateway/controllers/gatewayclass_controller.go +++ b/control-plane/api-gateway/controllers/gatewayclass_controller.go @@ -6,7 +6,6 @@ package controllers import ( "context" "fmt" - "github.com/go-logr/logr" "github.com/hashicorp/consul-k8s/control-plane/api/v1alpha1" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -42,7 +41,7 @@ type GatewayClassController struct { // Reconcile handles the reconciliation loop for GatewayClass objects. func (r *GatewayClassController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := r.Log.WithValues("gatewayClass", req.NamespacedName.Name) - log.Info("Reconciling GatewayClass") + log.V(1).Info("Reconciling GatewayClass") gc := &gwv1beta1.GatewayClass{} @@ -78,6 +77,11 @@ func (r *GatewayClassController) Reconcile(ctx context.Context, req ctrl.Request } // Remove our finalizer. if _, err := RemoveFinalizer(ctx, r.Client, gc, gatewayClassFinalizer); err != nil { + if k8serrors.IsConflict(err) { + log.V(1).Info("error removing finalizer for gatewayClass, will try to re-reconcile") + + return ctrl.Result{Requeue: true}, nil + } log.Error(err, "unable to remove finalizer") return ctrl.Result{}, err } @@ -87,6 +91,11 @@ func (r *GatewayClassController) Reconcile(ctx context.Context, req ctrl.Request // We are creating or updating the GatewayClass. didUpdate, err := EnsureFinalizer(ctx, r.Client, gc, gatewayClassFinalizer) if err != nil { + if k8serrors.IsConflict(err) { + log.V(1).Info("error adding finalizer for gatewayClass, will try to re-reconcile") + + return ctrl.Result{Requeue: true}, nil + } log.Error(err, "unable to add finalizer") return ctrl.Result{}, err } @@ -98,7 +107,12 @@ func (r *GatewayClassController) Reconcile(ctx context.Context, req ctrl.Request didUpdate, err = r.validateParametersRef(ctx, gc, log) if didUpdate { if err := r.Client.Status().Update(ctx, gc); err != nil { - log.Error(err, "unable to update GatewayClass") + if k8serrors.IsConflict(err) { + log.V(1).Info("error updating status for gatewayClass, will try to re-reconcile") + + return ctrl.Result{Requeue: true}, nil + } + log.Error(err, "unable to update status for GatewayClass") return ctrl.Result{}, err } return ctrl.Result{}, nil diff --git a/control-plane/api-gateway/controllers/gatewayclassconfig_controller.go b/control-plane/api-gateway/controllers/gatewayclassconfig_controller.go index 3889778348..878d6549f9 100644 --- a/control-plane/api-gateway/controllers/gatewayclassconfig_controller.go +++ b/control-plane/api-gateway/controllers/gatewayclassconfig_controller.go @@ -37,14 +37,14 @@ type GatewayClassConfigController struct { // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.8.3/pkg/reconcile func (r *GatewayClassConfigController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := r.Log.WithValues("gatewayClassConfig", req.NamespacedName.Name) - log.Info("Reconciling GatewayClassConfig ") + log.V(1).Info("Reconciling GatewayClassConfig ") gcc := &v1alpha1.GatewayClassConfig{} if err := r.Client.Get(ctx, req.NamespacedName, gcc); err != nil { if k8serrors.IsNotFound(err) { return ctrl.Result{}, nil } - r.Log.Error(err, "failed to get gateway class config") + log.Error(err, "failed to get gateway class config") return ctrl.Result{}, err } @@ -52,24 +52,33 @@ func (r *GatewayClassConfigController) Reconcile(ctx context.Context, req ctrl.R // We have a deletion, ensure we're not in use. used, err := gatewayClassConfigInUse(ctx, r.Client, gcc) if err != nil { - r.Log.Error(err, "failed to check if the gateway class config is still in use") + log.Error(err, "failed to check if the gateway class config is still in use") return ctrl.Result{}, err } if used { - r.Log.Info("gateway class config still in use") + log.Info("gateway class config still in use") // Requeue as to not block the reconciliation loop. return ctrl.Result{RequeueAfter: 10 * time.Second}, nil } // gcc is no longer in use. if _, err := RemoveFinalizer(ctx, r.Client, gcc, gatewayClassConfigFinalizer); err != nil { - r.Log.Error(err, "error removing gateway class config finalizer") + if k8serrors.IsConflict(err) { + log.V(1).Info("error removing gateway class config finalizer, will try to re-reconcile") + return ctrl.Result{Requeue: true}, nil + } + log.Error(err, "error removing gateway class config finalizer") return ctrl.Result{}, err } return ctrl.Result{}, nil } if _, err := EnsureFinalizer(ctx, r.Client, gcc, gatewayClassConfigFinalizer); err != nil { - r.Log.Error(err, "error adding gateway class config finalizer") + if k8serrors.IsConflict(err) { + log.V(1).Info("error adding gateway class config finalizer, will try to re-reconcile") + + return ctrl.Result{Requeue: true}, nil + } + log.Error(err, "error adding gateway class config finalizer") return ctrl.Result{}, err } diff --git a/control-plane/api-gateway/gatekeeper/deployment.go b/control-plane/api-gateway/gatekeeper/deployment.go index cc08e1bbef..3590caaf52 100644 --- a/control-plane/api-gateway/gatekeeper/deployment.go +++ b/control-plane/api-gateway/gatekeeper/deployment.go @@ -49,7 +49,7 @@ func (g *Gatekeeper) upsertDeployment(ctx context.Context, gateway gwv1beta1.Gat } if exists { - g.Log.Info("Existing Gateway Deployment found.") + g.Log.V(1).Info("Existing Gateway Deployment found.") // If the user has set the number of replicas, let's respect that. deployment.Spec.Replicas = existingDeployment.Spec.Replicas @@ -65,11 +65,11 @@ func (g *Gatekeeper) upsertDeployment(ctx context.Context, gateway gwv1beta1.Gat switch result { case controllerutil.OperationResultCreated: - g.Log.Info("Created Deployment") + g.Log.V(1).Info("Created Deployment") case controllerutil.OperationResultUpdated: - g.Log.Info("Updated Deployment") + g.Log.V(1).Info("Updated Deployment") case controllerutil.OperationResultNone: - g.Log.Info("No change to deployment") + g.Log.V(1).Info("No change to deployment") } return nil diff --git a/control-plane/api-gateway/gatekeeper/gatekeeper.go b/control-plane/api-gateway/gatekeeper/gatekeeper.go index 46243ff9a1..19444831ee 100644 --- a/control-plane/api-gateway/gatekeeper/gatekeeper.go +++ b/control-plane/api-gateway/gatekeeper/gatekeeper.go @@ -32,7 +32,7 @@ func New(log logr.Logger, client client.Client) *Gatekeeper { // Upsert creates or updates the resources for handling routing of network traffic. // This is done in order based on dependencies between resources. func (g *Gatekeeper) Upsert(ctx context.Context, gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClassConfig, config common.HelmConfig) error { - g.Log.Info(fmt.Sprintf("Upsert Gateway Deployment %s/%s", gateway.Namespace, gateway.Name)) + g.Log.V(1).Info(fmt.Sprintf("Upsert Gateway Deployment %s/%s", gateway.Namespace, gateway.Name)) if err := g.upsertRole(ctx, gateway, gcc, config); err != nil { return err @@ -60,7 +60,7 @@ func (g *Gatekeeper) Upsert(ctx context.Context, gateway gwv1beta1.Gateway, gcc // Delete removes the resources for handling routing of network traffic. // This is done in the reverse order of Upsert due to dependencies between resources. func (g *Gatekeeper) Delete(ctx context.Context, gatewayName types.NamespacedName) error { - g.Log.Info(fmt.Sprintf("Delete Gateway Deployment %s/%s", gatewayName.Namespace, gatewayName.Name)) + g.Log.V(1).Info(fmt.Sprintf("Delete Gateway Deployment %s/%s", gatewayName.Namespace, gatewayName.Name)) if err := g.deleteDeployment(ctx, gatewayName); err != nil { return err diff --git a/control-plane/api-gateway/gatekeeper/service.go b/control-plane/api-gateway/gatekeeper/service.go index 80272b7495..3b0e848899 100644 --- a/control-plane/api-gateway/gatekeeper/service.go +++ b/control-plane/api-gateway/gatekeeper/service.go @@ -43,11 +43,11 @@ func (g *Gatekeeper) upsertService(ctx context.Context, gateway gwv1beta1.Gatewa switch result { case controllerutil.OperationResultCreated: - g.Log.Info("Created Service") + g.Log.V(1).Info("Created Service") case controllerutil.OperationResultUpdated: - g.Log.Info("Updated Service") + g.Log.V(1).Info("Updated Service") case controllerutil.OperationResultNone: - g.Log.Info("No change to service") + g.Log.V(1).Info("No change to service") } return nil From 592e45702f3680f713d35511b41b39d3cc421b5e Mon Sep 17 00:00:00 2001 From: chappie <6537530+chapmanc@users.noreply.github.com> Date: Tue, 11 Jul 2023 14:33:21 -0600 Subject: [PATCH 064/120] HCP Observability acceptance test (#2254) --- acceptance/go.mod | 21 +- acceptance/go.sum | 128 ++++++++- acceptance/tests/cloud/basic_test.go | 1 + acceptance/tests/cloud/remote_dev_test.go | 264 ++++++++++++++++++ .../bases/cloud/service-intentions/acl.yaml | 15 + .../service-intentions/kustomization.yaml | 5 + .../consul/templates/server-statefulset.yaml | 1 + .../telemetry-collector-deployment.yaml | 2 +- 8 files changed, 431 insertions(+), 6 deletions(-) create mode 100644 acceptance/tests/cloud/remote_dev_test.go create mode 100644 acceptance/tests/fixtures/bases/cloud/service-intentions/acl.yaml create mode 100644 acceptance/tests/fixtures/bases/cloud/service-intentions/kustomization.yaml diff --git a/acceptance/go.mod b/acceptance/go.mod index 59cbbab79f..02ef978cf6 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -9,6 +9,7 @@ require ( github.com/hashicorp/consul/sdk v0.14.0-rc1 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.6.0 + github.com/hashicorp/hcp-sdk-go v0.50.0 github.com/hashicorp/serf v0.10.1 github.com/hashicorp/vault/api v1.8.3 github.com/stretchr/testify v1.8.3 @@ -24,6 +25,7 @@ require ( require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/armon/go-radix v1.0.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/aws/aws-sdk-go v1.44.262 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect @@ -39,9 +41,18 @@ require ( github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/analysis v0.21.4 // indirect + github.com/go-openapi/errors v0.20.3 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.1 // indirect + github.com/go-openapi/loads v0.21.2 // indirect + github.com/go-openapi/runtime v0.25.0 // indirect + github.com/go-openapi/spec v0.20.8 // indirect + github.com/go-openapi/strfmt v0.21.3 // indirect github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/validate v0.22.1 // indirect + github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -77,6 +88,7 @@ require ( github.com/mattn/go-isatty v0.0.17 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/miekg/dns v1.1.50 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.0 // indirect @@ -88,6 +100,8 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/run v1.0.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -98,14 +112,18 @@ require ( github.com/prometheus/procfs v0.8.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/urfave/cli v1.22.2 // indirect + go.mongodb.org/mongo-driver v1.11.0 // indirect + go.opentelemetry.io/otel v1.11.1 // indirect + go.opentelemetry.io/otel/trace v1.11.1 // indirect go.uber.org/atomic v1.9.0 // indirect golang.org/x/crypto v0.1.0 // indirect golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect golang.org/x/mod v0.9.0 // indirect golang.org/x/net v0.10.0 // indirect - golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect + golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sys v0.8.0 // indirect golang.org/x/term v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect @@ -119,7 +137,6 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/component-base v0.26.3 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index 578a95b1dd..b3aaefe655 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -91,6 +91,9 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -214,31 +217,88 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= +github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= +github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= +github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= +github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= +github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= +github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= +github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= +github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE= +github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -277,6 +337,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -291,6 +352,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -393,6 +455,8 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcp-sdk-go v0.50.0 h1:vOUpVf4MQF/gtoBukuoYKs/i6KinTSpP5jhKCvsZ2bc= +github.com/hashicorp/hcp-sdk-go v0.50.0/go.mod h1:hZqky4HEzsKwvLOt4QJlZUrjeQmb4UCZUhDP2HyQFfc= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= @@ -421,6 +485,7 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -438,10 +503,13 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -460,8 +528,11 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -492,6 +563,8 @@ github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -501,6 +574,7 @@ github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -518,6 +592,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -525,8 +600,11 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -541,11 +619,14 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -595,6 +676,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uY github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= @@ -612,9 +695,12 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -640,6 +726,7 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -647,6 +734,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -656,8 +745,14 @@ github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -666,11 +761,21 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= +go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= +go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= +go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs= +go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= +go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= @@ -683,6 +788,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -690,8 +796,10 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -771,8 +879,10 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -785,12 +895,14 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -812,10 +924,13 @@ golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -854,6 +969,7 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -903,9 +1019,13 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1056,6 +1176,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= @@ -1082,7 +1203,9 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= @@ -1110,8 +1233,7 @@ k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ= k8s.io/cloud-provider v0.17.0/go.mod h1:Ze4c3w2C0bRsjkBUoHpFi+qWe3ob1wI2/7cUn+YQIDE= k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= -k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g= -k8s.io/component-base v0.26.3/go.mod h1:5kj1kZYwSC6ZstHJN7oHBqcJC6yyn41eR+Sqa/mQc8E= +k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4= k8s.io/csi-translation-lib v0.17.0/go.mod h1:HEF7MEz7pOLJCnxabi45IPkhSsE/KmxPQksuCrHKWls= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= diff --git a/acceptance/tests/cloud/basic_test.go b/acceptance/tests/cloud/basic_test.go index 8278309ff3..7a0a31430a 100644 --- a/acceptance/tests/cloud/basic_test.go +++ b/acceptance/tests/cloud/basic_test.go @@ -150,6 +150,7 @@ func TestBasicCloud(t *testing.T) { releaseName := helpers.RandomName() helmValues := map[string]string{ + "global.imagePullPolicy": "IfNotPresent", "global.cloud.enabled": "true", "global.cloud.resourceId.secretName": resourceSecretName, "global.cloud.resourceId.secretKey": resourceSecretKey, diff --git a/acceptance/tests/cloud/remote_dev_test.go b/acceptance/tests/cloud/remote_dev_test.go new file mode 100644 index 0000000000..aa7dbe70c7 --- /dev/null +++ b/acceptance/tests/cloud/remote_dev_test.go @@ -0,0 +1,264 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package cloud + +import ( + "crypto/tls" + "encoding/json" + "os" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" + "github.com/hashicorp/consul-k8s/acceptance/framework/environment" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + + hcpgnm "github.com/hashicorp/hcp-sdk-go/clients/cloud-global-network-manager-service/preview/2022-02-15/client/global_network_manager_service" + "github.com/hashicorp/hcp-sdk-go/clients/cloud-global-network-manager-service/preview/2022-02-15/models" + hcpcfg "github.com/hashicorp/hcp-sdk-go/config" + "github.com/hashicorp/hcp-sdk-go/httpclient" + "github.com/hashicorp/hcp-sdk-go/resource" +) + +type DevTokenResponse struct { + Token string `json:"token"` +} + +type hcp struct { + ResourceID string + ClientID string + ClientSecret string + AuthURL string + APIHostname string + ScadaAddress string +} + +func TestRemoteDevCloud(t *testing.T) { + _, rIDok := os.LookupEnv("HCP_RESOURCE_ID") + _, cIDok := os.LookupEnv("HCP_CLIENT_ID") + _, cSECok := os.LookupEnv("HCP_CLIENT_SECRET") + + if !rIDok || !cIDok || !cSECok { + t.Log("Must set HCP_RESOURCE_ID, HCP_CLIENT_ID and HCP_CLIENT_SECRET") + t.FailNow() + } + + apiHost := os.Getenv("HCP_AUTH_URL") + if apiHost == "" { + apiHost = "https://api.hcp.dev" + } + authURL := os.Getenv("HCP_API_HOST") + if authURL == "" { + authURL = "https://auth.idp.hcp.dev" + } + scadaAddr := os.Getenv("HCP_SCADA_ADDRESS") + if scadaAddr == "" { + scadaAddr = "scada.internal.hcp.dev:7224" + } + + ctx := suite.Environment().DefaultContext(t) + + kubectlOptions := ctx.KubectlOptions(t) + ns := kubectlOptions.Namespace + k8sClient := environment.KubernetesClientFromOptions(t, kubectlOptions) + + var ( + resourceSecretName = "resource-sec-name" + resourceSecretKey = "resource-sec-key" + resourceSecretKeyValue = os.Getenv("HCP_RESOURCE_ID") + + clientIDSecretName = "clientid-sec-name" + clientIDSecretKey = "clientid-sec-key" + clientIDSecretKeyValue = os.Getenv("HCP_CLIENT_ID") + + clientSecretName = "client-sec-name" + clientSecretKey = "client-sec-key" + clientSecretKeyValue = os.Getenv("HCP_CLIENT_SECRET") + + apiHostSecretName = "apihost-sec-name" + apiHostSecretKey = "apihost-sec-key" + apiHostSecretKeyValue = apiHost + + authUrlSecretName = "authurl-sec-name" + authUrlSecretKey = "authurl-sec-key" + authUrlSecretKeyValue = authURL + + scadaAddressSecretName = "scadaaddress-sec-name" + scadaAddressSecretKey = "scadaaddress-sec-key" + scadaAddressSecretKeyValue = scadaAddr + + bootstrapTokenSecretName = "bootstrap-token" + bootstrapTokenSecretKey = "token" + ) + + hcpCfg := hcp{ + ResourceID: resourceSecretKeyValue, + ClientID: clientIDSecretKeyValue, + ClientSecret: clientSecretKeyValue, + AuthURL: authUrlSecretKeyValue, + APIHostname: apiHostSecretKeyValue, + ScadaAddress: scadaAddressSecretKeyValue, + } + + aclToken := hcpCfg.fetchAgentBootstrapConfig(t) + + cfg := suite.Config() + consul.CreateK8sSecret(t, k8sClient, cfg, ns, resourceSecretName, resourceSecretKey, resourceSecretKeyValue) + consul.CreateK8sSecret(t, k8sClient, cfg, ns, clientIDSecretName, clientIDSecretKey, clientIDSecretKeyValue) + consul.CreateK8sSecret(t, k8sClient, cfg, ns, clientSecretName, clientSecretKey, clientSecretKeyValue) + consul.CreateK8sSecret(t, k8sClient, cfg, ns, apiHostSecretName, apiHostSecretKey, apiHostSecretKeyValue) + consul.CreateK8sSecret(t, k8sClient, cfg, ns, authUrlSecretName, authUrlSecretKey, authUrlSecretKeyValue) + consul.CreateK8sSecret(t, k8sClient, cfg, ns, scadaAddressSecretName, scadaAddressSecretKey, scadaAddressSecretKeyValue) + consul.CreateK8sSecret(t, k8sClient, cfg, ns, bootstrapTokenSecretName, bootstrapTokenSecretKey, aclToken) + + releaseName := helpers.RandomName() + + helmValues := map[string]string{ + "global.imagePullPolicy": "IfNotPresent", + "global.cloud.enabled": "true", + "global.cloud.resourceId.secretName": resourceSecretName, + "global.cloud.resourceId.secretKey": resourceSecretKey, + + "global.cloud.clientId.secretName": clientIDSecretName, + "global.cloud.clientId.secretKey": clientIDSecretKey, + + "global.cloud.clientSecret.secretName": clientSecretName, + "global.cloud.clientSecret.secretKey": clientSecretKey, + + "global.cloud.apiHost.secretName": apiHostSecretName, + "global.cloud.apiHost.secretKey": apiHostSecretKey, + + "global.cloud.authUrl.secretName": authUrlSecretName, + "global.cloud.authUrl.secretKey": authUrlSecretKey, + + "global.cloud.scadaAddress.secretName": scadaAddressSecretName, + "global.cloud.scadaAddress.secretKey": scadaAddressSecretKey, + "connectInject.default": "true", + + "global.acls.manageSystemACLs": "true", + "global.acls.bootstrapToken.secretName": bootstrapTokenSecretName, + "global.acls.bootstrapToken.secretKey": bootstrapTokenSecretKey, + + "global.gossipEncryption.autoGenerate": "false", + "global.tls.enabled": "true", + "global.tls.enableAutoEncrypt": "true", + + "telemetryCollector.enabled": "true", + "telemetryCollector.cloud.clientId.secretName": clientIDSecretName, + "telemetryCollector.cloud.clientId.secretKey": clientIDSecretKey, + + "telemetryCollector.cloud.clientSecret.secretName": clientSecretName, + "telemetryCollector.cloud.clientSecret.secretKey": clientSecretKey, + // Either we set the global.trustedCAs (make sure it's idented exactly) or we + // set TLS to insecure + + "telemetryCollector.extraEnvironmentVars.HCP_API_ADDRESS": apiHostSecretKeyValue, + } + + if cfg.ConsulImage != "" { + helmValues["global.image"] = cfg.ConsulImage + } + if cfg.ConsulCollectorImage != "" { + helmValues["telemetryCollector.image"] = cfg.ConsulCollectorImage + } + + consulCluster := consul.NewHelmCluster(t, helmValues, suite.Environment().DefaultContext(t), cfg, releaseName) + consulCluster.Create(t) + + logger.Log(t, "setting acl permissions for collector and services") + aclDir := "../fixtures/bases/cloud/service-intentions" + k8s.KubectlApplyK(t, ctx.KubectlOptions(t), aclDir) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + k8s.KubectlDeleteK(t, ctx.KubectlOptions(t), aclDir) + }) + + logger.Log(t, "creating static-server deployment") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + time.Sleep(1 * time.Hour) + + // TODO: add in test assertions here + +} + +// fetchAgentBootstrapConfig use the resource-id, client-id, and client-secret +// to call to the agent bootstrap config endpoint and parse the response into a +// CloudBootstrapConfig struct. +func (c *hcp) fetchAgentBootstrapConfig(t *testing.T) string { + cfg, err := c.HCPConfig() + require.NoError(t, err) + logger.Log(t, "Fetching Consul cluster configuration from HCP") + httpClientCfg := httpclient.Config{ + HCPConfig: cfg, + } + clientRuntime, err := httpclient.New(httpClientCfg) + require.NoError(t, err) + + hcpgnmClient := hcpgnm.New(clientRuntime, nil) + clusterResource, err := resource.FromString(c.ResourceID) + require.NoError(t, err) + + params := hcpgnm.NewAgentBootstrapConfigParams(). + WithID(clusterResource.ID). + WithLocationOrganizationID(clusterResource.Organization). + WithLocationProjectID(clusterResource.Project) + + resp, err := hcpgnmClient.AgentBootstrapConfig(params, nil) + require.NoError(t, err) + + bootstrapConfig := resp.GetPayload() + logger.Log(t, "HCP configuration successfully fetched.") + + return c.parseBootstrapConfigResponse(t, bootstrapConfig) +} + +// ConsulConfig represents 'cluster.consul_config' in the response +// fetched from the agent bootstrap config endpoint in HCP. +type ConsulConfig struct { + ACL ACL `json:"acl"` +} + +// ACL represents 'cluster.consul_config.acl' in the response +// fetched from the agent bootstrap config endpoint in HCP. +type ACL struct { + Tokens Tokens `json:"tokens"` +} + +// Tokens represents 'cluster.consul_config.acl.tokens' in the +// response fetched from the agent bootstrap config endpoint in HCP. +type Tokens struct { + Agent string `json:"agent"` + InitialManagement string `json:"initial_management"` +} + +// parseBootstrapConfigResponse unmarshals the boostrap parseBootstrapConfigResponse +// and also sets the HCPConfig values to return CloudBootstrapConfig struct. +func (c *hcp) parseBootstrapConfigResponse(t *testing.T, bootstrapRepsonse *models.HashicorpCloudGlobalNetworkManager20220215AgentBootstrapResponse) string { + + var consulConfig ConsulConfig + err := json.Unmarshal([]byte(bootstrapRepsonse.Bootstrap.ConsulConfig), &consulConfig) + require.NoError(t, err) + + return consulConfig.ACL.Tokens.InitialManagement +} + +func (c *hcp) HCPConfig(opts ...hcpcfg.HCPConfigOption) (hcpcfg.HCPConfig, error) { + if c.ClientID != "" && c.ClientSecret != "" { + opts = append(opts, hcpcfg.WithClientCredentials(c.ClientID, c.ClientSecret)) + } + if c.AuthURL != "" { + opts = append(opts, hcpcfg.WithAuth(c.AuthURL, &tls.Config{})) + } + if c.APIHostname != "" { + opts = append(opts, hcpcfg.WithAPI(c.APIHostname, &tls.Config{})) + } + if c.ScadaAddress != "" { + opts = append(opts, hcpcfg.WithSCADA(c.ScadaAddress, &tls.Config{})) + } + opts = append(opts, hcpcfg.FromEnv(), hcpcfg.WithoutBrowserLogin()) + return hcpcfg.NewHCPConfig(opts...) +} diff --git a/acceptance/tests/fixtures/bases/cloud/service-intentions/acl.yaml b/acceptance/tests/fixtures/bases/cloud/service-intentions/acl.yaml new file mode 100644 index 0000000000..fb3f77f496 --- /dev/null +++ b/acceptance/tests/fixtures/bases/cloud/service-intentions/acl.yaml @@ -0,0 +1,15 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceIntentions +metadata: + name: consul-telemetry-collector +spec: + destination: + name: 'consul-telemetry-collector' + sources: + - name: '*' + action: allow + + + \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/cloud/service-intentions/kustomization.yaml b/acceptance/tests/fixtures/bases/cloud/service-intentions/kustomization.yaml new file mode 100644 index 0000000000..9c19bf4ca3 --- /dev/null +++ b/acceptance/tests/fixtures/bases/cloud/service-intentions/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - acl.yaml \ No newline at end of file diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 0bde9b881a..9efbcb8085 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -241,6 +241,7 @@ spec: containers: - name: consul image: "{{ default .Values.global.image .Values.server.image }}" + imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: ADVERTISE_IP valueFrom: diff --git a/charts/consul/templates/telemetry-collector-deployment.yaml b/charts/consul/templates/telemetry-collector-deployment.yaml index 62b8868f1f..b729273dd8 100644 --- a/charts/consul/templates/telemetry-collector-deployment.yaml +++ b/charts/consul/templates/telemetry-collector-deployment.yaml @@ -150,7 +150,7 @@ spec: containers: - name: consul-telemetry-collector image: {{ .Values.telemetryCollector.image }} - imagePullPolicy: Always + imagePullPolicy: {{ .Values.global.imagePullPolicy }} ports: - containerPort: 9090 name: metrics From 858228683c05d9d0e0727ad5f120b75f30ac6480 Mon Sep 17 00:00:00 2001 From: chappie <6537530+chapmanc@users.noreply.github.com> Date: Tue, 11 Jul 2023 14:59:26 -0600 Subject: [PATCH 065/120] HCP bootstrap preset to always downcase datacenter (#2551) * Lowercase datacenter name from HCP bootstrap response * Add test cases to cloud bootstrap --- cli/preset/cloud_preset.go | 3 ++- cli/preset/cloud_preset_test.go | 34 +++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/cli/preset/cloud_preset.go b/cli/preset/cloud_preset.go index 732bad1b14..cbc335ae17 100644 --- a/cli/preset/cloud_preset.go +++ b/cli/preset/cloud_preset.go @@ -8,6 +8,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" "github.com/hashicorp/consul-k8s/cli/common" "github.com/hashicorp/consul-k8s/cli/common/terminal" @@ -235,7 +236,7 @@ connectInject: enabled: true controller: enabled: true -`, cfg.BootstrapResponse.Cluster.ID, secretNameServerCA, corev1.TLSCertKey, +`, strings.ToLower(cfg.BootstrapResponse.Cluster.ID), secretNameServerCA, corev1.TLSCertKey, secretNameGossipKey, secretKeyGossipKey, secretNameBootstrapToken, secretKeyBootstrapToken, secretNameHCPResourceID, secretKeyHCPResourceID, diff --git a/cli/preset/cloud_preset_test.go b/cli/preset/cloud_preset_test.go index 770b47ba5c..d905cb4088 100644 --- a/cli/preset/cloud_preset_test.go +++ b/cli/preset/cloud_preset_test.go @@ -43,7 +43,7 @@ const ( { "cluster": { - "id": "dc1", + "id": "Dc1", "bootstrap_expect" : 3 }, "bootstrap": @@ -63,7 +63,7 @@ const ( var validBootstrapReponse *models.HashicorpCloudGlobalNetworkManager20220215AgentBootstrapResponse = &models.HashicorpCloudGlobalNetworkManager20220215AgentBootstrapResponse{ Bootstrap: &models.HashicorpCloudGlobalNetworkManager20220215ClusterBootstrap{ - ID: "dc1", + ID: "Dc1", GossipKey: "Wa6/XFAnYy0f9iqVH2iiG+yore3CqHSemUy4AIVTa/w=", BootstrapExpect: 3, ServerTLS: &models.HashicorpCloudGlobalNetworkManager20220215ServerTLS{ @@ -558,12 +558,30 @@ telemetryCollector: cloudPreset := &CloudPreset{} - testCases := []struct { - description string + testCases := map[string]struct { config *CloudBootstrapConfig expectedYaml string }{ - {"Config including optional parameters", + "Config_including_optional_parameters_with_mixedcase_DC": { + &CloudBootstrapConfig{ + BootstrapResponse: &models.HashicorpCloudGlobalNetworkManager20220215AgentBootstrapResponse{ + Cluster: &models.HashicorpCloudGlobalNetworkManager20220215Cluster{ + BootstrapExpect: 3, + ID: "Dc1", + }, + }, + HCPConfig: HCPConfig{ + ResourceID: "consul-hcp-resource-id", + ClientID: "consul-hcp-client-id", + ClientSecret: "consul-hcp-client-secret", + AuthURL: "consul-hcp-auth-url", + APIHostname: "consul-hcp-api-host", + ScadaAddress: "consul-hcp-scada-address", + }, + }, + expectedFull, + }, + "Config_including_optional_parameters": { &CloudBootstrapConfig{ BootstrapResponse: &models.HashicorpCloudGlobalNetworkManager20220215AgentBootstrapResponse{ Cluster: &models.HashicorpCloudGlobalNetworkManager20220215Cluster{ @@ -582,7 +600,7 @@ telemetryCollector: }, expectedFull, }, - {"Config without optional parameters", + "Config_without_optional_parameters": { &CloudBootstrapConfig{ BootstrapResponse: &models.HashicorpCloudGlobalNetworkManager20220215AgentBootstrapResponse{ Cluster: &models.HashicorpCloudGlobalNetworkManager20220215Cluster{ @@ -599,8 +617,8 @@ telemetryCollector: expectedWithoutOptional, }, } - for _, tc := range testCases { - t.Run(tc.description, func(t *testing.T) { + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { cloudHelmValues := cloudPreset.getHelmConfigWithMapSecretNames(tc.config) require.NotNil(t, cloudHelmValues) valuesYaml, err := yaml.Marshal(cloudHelmValues) From 4f064795810b2db052109bcbff9c0f18206d44c5 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 11 Jul 2023 16:53:11 -0500 Subject: [PATCH 066/120] api-gateway: when multiple listeners have the same port, only add to K8s Service once (#2413) * Modify unit tests to include multiple listeners w/ same port Running the tests on this commit will demonstrate the bug * When multiple listeners have the same port, only add to K8s Service once * Add changelog entry --- .changelog/2413.txt | 3 +++ control-plane/api-gateway/gatekeeper/gatekeeper_test.go | 7 +++++++ control-plane/api-gateway/gatekeeper/service.go | 8 ++++++++ 3 files changed, 18 insertions(+) create mode 100644 .changelog/2413.txt diff --git a/.changelog/2413.txt b/.changelog/2413.txt new file mode 100644 index 0000000000..89755b23a7 --- /dev/null +++ b/.changelog/2413.txt @@ -0,0 +1,3 @@ +```release-note:bug +api-gateway: Fix creation of invalid Kubernetes Service when multiple Gateway listeners have the same port. +``` diff --git a/control-plane/api-gateway/gatekeeper/gatekeeper_test.go b/control-plane/api-gateway/gatekeeper/gatekeeper_test.go index ba58cb441f..069643e301 100644 --- a/control-plane/api-gateway/gatekeeper/gatekeeper_test.go +++ b/control-plane/api-gateway/gatekeeper/gatekeeper_test.go @@ -40,12 +40,19 @@ var ( Name: "Listener 1", Port: 8080, Protocol: "TCP", + Hostname: common.PointerTo(gwv1beta1.Hostname("example.com")), }, { Name: "Listener 2", Port: 8081, Protocol: "TCP", }, + { + Name: "Listener 3", + Port: 8080, + Protocol: "TCP", + Hostname: common.PointerTo(gwv1beta1.Hostname("example.net")), + }, } ) diff --git a/control-plane/api-gateway/gatekeeper/service.go b/control-plane/api-gateway/gatekeeper/service.go index 3b0e848899..d534ad50d7 100644 --- a/control-plane/api-gateway/gatekeeper/service.go +++ b/control-plane/api-gateway/gatekeeper/service.go @@ -65,14 +65,22 @@ func (g *Gatekeeper) deleteService(ctx context.Context, gwName types.NamespacedN } func (g *Gatekeeper) service(gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClassConfig) *corev1.Service { + seenPorts := map[gwv1beta1.PortNumber]struct{}{} ports := []corev1.ServicePort{} for _, listener := range gateway.Spec.Listeners { + if _, seen := seenPorts[listener.Port]; seen { + // We've already added this listener's port to the Service + continue + } + ports = append(ports, corev1.ServicePort{ Name: string(listener.Name), // only TCP-based services are supported for now Protocol: corev1.ProtocolTCP, Port: int32(listener.Port), }) + + seenPorts[listener.Port] = struct{}{} } // Copy annotations from the Gateway, filtered by those allowed by the GatewayClassConfig. From b8be6a0d9ab9ea2ab941c74207cd68d0af2454cb Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 11 Jul 2023 17:35:12 -0500 Subject: [PATCH 067/120] NET-4482: set route condition appropriately when parent ref includes non-existent section (#2420) * Set route accepted condition appropriately when no listener with section name matching parent * Adjust error message for bind errors that aren't specific to one listener * Include section name in message for NoMatchingParent when available * Add unit test coverage for conditions derived from binding results * Add changelog entry --- .changelog/2420.txt | 3 + control-plane/api-gateway/binding/result.go | 22 ++++-- .../api-gateway/binding/result_test.go | 67 +++++++++++++++++++ .../api-gateway/binding/route_binding.go | 23 +++++-- 4 files changed, 104 insertions(+), 11 deletions(-) create mode 100644 .changelog/2420.txt create mode 100644 control-plane/api-gateway/binding/result_test.go diff --git a/.changelog/2420.txt b/.changelog/2420.txt new file mode 100644 index 0000000000..86776497c4 --- /dev/null +++ b/.changelog/2420.txt @@ -0,0 +1,3 @@ +```release-note:bug +api-gateway: set route condition appropriately when parent ref includes non-existent section name +``` diff --git a/control-plane/api-gateway/binding/result.go b/control-plane/api-gateway/binding/result.go index fd2eaca829..b148e441e2 100644 --- a/control-plane/api-gateway/binding/result.go +++ b/control-plane/api-gateway/binding/result.go @@ -34,6 +34,7 @@ var ( errRouteNoMatchingListenerHostname = errors.New("listener cannot bind route with a non-aligned hostname") errRouteInvalidKind = errors.New("invalid backend kind") errRouteBackendNotFound = errors.New("backend not found") + errRouteNoMatchingParent = errors.New("no matching parent") ) // routeValidationResult holds the result of validating a route globally, in other @@ -128,13 +129,17 @@ type bindResult struct { type bindResults []bindResult // Error constructs a human readable error for bindResults, containing any errors that a route -// had in binding to a gateway, note that this is only used if a route failed to bind to every +// had in binding to a gateway. Note that this is only used if a route failed to bind to every // listener it attempted to bind to. func (b bindResults) Error() string { messages := []string{} for _, result := range b { if result.err != nil { - messages = append(messages, fmt.Sprintf("%s: %s", result.section, result.err.Error())) + message := result.err.Error() + if result.section != "" { + message = fmt.Sprintf("%s: %s", result.section, result.err.Error()) + } + messages = append(messages, message) } } @@ -171,13 +176,16 @@ func (b bindResults) Condition() metav1.Condition { // if we only have a single binding error, we can get more specific if len(b) == 1 { for _, result := range b { - // if we have a hostname mismatch error, then use the more specific reason - if result.err == errRouteNoMatchingListenerHostname { + switch result.err { + case errRouteNoMatchingListenerHostname: + // if we have a hostname mismatch error, then use the more specific reason reason = "NoMatchingListenerHostname" - } - // or if we have a ref not permitted, then use that - if result.err == errRefNotPermitted { + case errRefNotPermitted: + // or if we have a ref not permitted, then use that reason = "RefNotPermitted" + case errRouteNoMatchingParent: + // or if the route declares a parent that we can't find + reason = "NoMatchingParent" } } } diff --git a/control-plane/api-gateway/binding/result_test.go b/control-plane/api-gateway/binding/result_test.go new file mode 100644 index 0000000000..c6987cdaeb --- /dev/null +++ b/control-plane/api-gateway/binding/result_test.go @@ -0,0 +1,67 @@ +package binding + +import ( + "errors" + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestBindResults_Condition(t *testing.T) { + testCases := []struct { + Name string + Results bindResults + Expected metav1.Condition + }{ + { + Name: "route successfully bound", + Results: bindResults{{section: "", err: nil}}, + Expected: metav1.Condition{Type: "Accepted", Status: "True", Reason: "Accepted", Message: "route accepted"}, + }, + { + Name: "multiple bind results", + Results: bindResults{ + {section: "abc", err: errRouteNoMatchingListenerHostname}, + {section: "def", err: errRouteNoMatchingParent}, + }, + Expected: metav1.Condition{Type: "Accepted", Status: "False", Reason: "NotAllowedByListeners", Message: "abc: listener cannot bind route with a non-aligned hostname; def: no matching parent"}, + }, + { + Name: "no matching listener hostname error", + Results: bindResults{{section: "abc", err: errRouteNoMatchingListenerHostname}}, + Expected: metav1.Condition{Type: "Accepted", Status: "False", Reason: "NoMatchingListenerHostname", Message: "abc: listener cannot bind route with a non-aligned hostname"}, + }, + { + Name: "ref not permitted error", + Results: bindResults{{section: "abc", err: errRefNotPermitted}}, + Expected: metav1.Condition{Type: "Accepted", Status: "False", Reason: "RefNotPermitted", Message: "abc: reference not permitted due to lack of ReferenceGrant"}, + }, + { + Name: "no matching parent error", + Results: bindResults{{section: "hello1", err: errRouteNoMatchingParent}}, + Expected: metav1.Condition{Type: "Accepted", Status: "False", Reason: "NoMatchingParent", Message: "hello1: no matching parent"}, + }, + { + Name: "bind result without section name", + Results: bindResults{{section: "", err: errRouteNoMatchingParent}}, + Expected: metav1.Condition{Type: "Accepted", Status: "False", Reason: "NoMatchingParent", Message: "no matching parent"}, + }, + { + Name: "unhandled error type", + Results: bindResults{{section: "abc", err: errors.New("you don't know me")}}, + Expected: metav1.Condition{Type: "Accepted", Status: "False", Reason: "NotAllowedByListeners", Message: "abc: you don't know me"}, + }, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("%s_%s", t.Name(), tc.Name), func(t *testing.T) { + actual := tc.Results.Condition() + assert.Equalf(t, tc.Expected.Type, actual.Type, "expected condition with type %q but got %q", tc.Expected.Type, actual.Type) + assert.Equalf(t, tc.Expected.Status, actual.Status, "expected condition with status %q but got %q", tc.Expected.Status, actual.Status) + assert.Equalf(t, tc.Expected.Reason, actual.Reason, "expected condition with reason %q but got %q", tc.Expected.Reason, actual.Reason) + assert.Equalf(t, tc.Expected.Message, actual.Message, "expected condition with message %q but got %q", tc.Expected.Message, actual.Message) + }) + } +} diff --git a/control-plane/api-gateway/binding/route_binding.go b/control-plane/api-gateway/binding/route_binding.go index 36fcda0204..8b2e66e761 100644 --- a/control-plane/api-gateway/binding/route_binding.go +++ b/control-plane/api-gateway/binding/route_binding.go @@ -104,7 +104,22 @@ func (r *Binder) bindRoute(route client.Object, boundCount map[gwv1beta1.Section for _, ref := range filteredParents { var result bindResults - for _, listener := range listenersFor(&r.config.Gateway, ref.SectionName) { + listeners := listenersFor(&r.config.Gateway, ref.SectionName) + + // If there are no matching listeners, then we failed to find the parent + if len(listeners) == 0 { + var sectionName gwv1beta1.SectionName + if ref.SectionName != nil { + sectionName = *ref.SectionName + } + + result = append(result, bindResult{ + section: sectionName, + err: errRouteNoMatchingParent, + }) + } + + for _, listener := range listeners { if !routeKindIsAllowedForListener(supportedKindsForProtocol[listener.Protocol], groupKind) { result = append(result, bindResult{ section: listener.Name, @@ -179,9 +194,9 @@ func filterParentRefs(gateway types.NamespacedName, namespace string, refs []gwv return references } -// listenersFor returns the listeners corresponding the given section name. If the section -// name is actually specified, the returned set should just have one listener, if it is -// unspecified, the all gatweway listeners should be returned. +// listenersFor returns the listeners corresponding to the given section name. If the section +// name is actually specified, the returned set will only contain the named listener. If it is +// unspecified, then all gateway listeners will be returned. func listenersFor(gateway *gwv1beta1.Gateway, name *gwv1beta1.SectionName) []gwv1beta1.Listener { listeners := []gwv1beta1.Listener{} for _, listener := range gateway.Spec.Listeners { From 73959e7acc0f0d6995bf749df2ec3c845d29b033 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Wed, 12 Jul 2023 10:04:36 -0400 Subject: [PATCH 068/120] test: update nightly tests to consul 1.17-dev (#2556) --- .github/workflows/merge.yml | 2 +- .github/workflows/nightly-acceptance.yml | 2 +- .github/workflows/nightly-api-gateway-conformance.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index b6037e0af3..201df1dadd 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -11,7 +11,7 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.16-dev # Consul's enterprise version to use in tests. We use this consul image on release branches too + CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.17-dev # Consul's enterprise version to use in tests. We use this consul image on release branches too BRANCH: ${{ github.head_ref || github.ref_name }} CONTEXT: "merge" SHA: ${{ github.event.pull_request.head.sha || github.sha }} diff --git a/.github/workflows/nightly-acceptance.yml b/.github/workflows/nightly-acceptance.yml index 6414d6a611..4d437b4990 100644 --- a/.github/workflows/nightly-acceptance.yml +++ b/.github/workflows/nightly-acceptance.yml @@ -8,7 +8,7 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.16-dev # Consul's enterprise version to use in tests + CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.17-dev # Consul's enterprise version to use in tests BRANCH: ${{ github.ref_name }} CONTEXT: "nightly" diff --git a/.github/workflows/nightly-api-gateway-conformance.yml b/.github/workflows/nightly-api-gateway-conformance.yml index cd63ee8467..5038ffdb93 100644 --- a/.github/workflows/nightly-api-gateway-conformance.yml +++ b/.github/workflows/nightly-api-gateway-conformance.yml @@ -9,7 +9,7 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.16-dev # Consul's enterprise version to use in tests + CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.17-dev # Consul's enterprise version to use in tests BRANCH: ${{ github.ref_name }} CONTEXT: "nightly" From 65c4e7431013a1eb5416a596674a54c6a44a4499 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:29:11 -0700 Subject: [PATCH 069/120] Update Release Scripts (#2558) * update environment variables with CONSUL_K8s prefix - This will let us check that we have all the environment variables set more easily with `printenv | grep "CONSUL_K8S"` * update imageConsulDataplane without quotes - this makes it consistent with the other images - allows scripting to work similarly to other images * updated utils script - handle replace case where consul-enterprise is in the values.yaml file and charts.yaml file - handle adding pre-release tag in changelog - handle updating consul-dataplane --- Makefile | 42 ++++++----- charts/consul/values.yaml | 2 +- .../build-support/functions/10-util.sh | 71 ++++++++++++++----- 3 files changed, 78 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index de35275868..1b7e4d8d7b 100644 --- a/Makefile +++ b/Makefile @@ -209,38 +209,42 @@ eks-test-packages: aks-test-packages: @./control-plane/build-support/scripts/set_test_package_matrix.sh "acceptance/ci-inputs/aks_acceptance_test_packages.yaml" - # ===========> Release Targets +check-env: + @printenv | grep "CONSUL_K8S" prepare-release: ## Sets the versions, updates changelog to prepare this repository to release -ifndef RELEASE_VERSION - $(error RELEASE_VERSION is required) +ifndef CONSUL_K8S_RELEASE_VERSION + $(error CONSUL_K8S_RELEASE_VERSION is required) endif -ifndef RELEASE_DATE - $(error RELEASE_DATE is required, use format , (ex. October 4, 2022)) +ifndef CONSUL_K8S_RELEASE_DATE + $(error CONSUL_K8S_RELEASE_DATE is required, use format , (ex. October 4, 2022)) endif -ifndef LAST_RELEASE_GIT_TAG - $(error LAST_RELEASE_GIT_TAG is required) +ifndef CONSUL_K8S_LAST_RELEASE_GIT_TAG + $(error CONSUL_K8S_LAST_RELEASE_GIT_TAG is required) endif -ifndef CONSUL_VERSION - $(error CONSUL_VERSION is required) +ifndef CONSUL_K8S_CONSUL_VERSION + $(error CONSUL_K8S_CONSUL_VERSION is required) endif - source $(CURDIR)/control-plane/build-support/scripts/functions.sh; prepare_release $(CURDIR) $(RELEASE_VERSION) "$(RELEASE_DATE)" $(LAST_RELEASE_GIT_TAG) $(CONSUL_VERSION) $(PRERELEASE_VERSION) + source $(CURDIR)/control-plane/build-support/scripts/functions.sh; prepare_release $(CURDIR) $(CONSUL_K8S_RELEASE_VERSION) "$(CONSUL_K8S_RELEASE_DATE)" $(CONSUL_K8S_LAST_RELEASE_GIT_TAG) $(CONSUL_K8S_CONSUL_VERSION) $(CONSUL_K8S_CONSUL_DATAPLANE_VERSION) $(CONSUL_K8S_PRERELEASE_VERSION) prepare-dev: -ifndef RELEASE_VERSION - $(error RELEASE_VERSION is required) +ifndef CONSUL_K8S_RELEASE_VERSION + $(error CONSUL_K8S_RELEASE_VERSION is required) +endif +ifndef CONSUL_K8S_RELEASE_DATE + $(error CONSUL_K8S_RELEASE_DATE is required, use format , (ex. October 4, 2022)) endif -ifndef RELEASE_DATE - $(error RELEASE_DATE is required, use format , (ex. October 4, 2022)) +ifndef CONSUL_K8S_NEXT_RELEASE_VERSION + $(error CONSUL_K8S_NEXT_RELEASE_VERSION is required) endif -ifndef NEXT_RELEASE_VERSION - $(error NEXT_RELEASE_VERSION is required) +ifndef CONSUL_K8S_NEXT_CONSUL_VERSION + $(error CONSUL_K8S_NEXT_CONSUL_VERSION is required) endif -ifndef NEXT_CONSUL_VERSION - $(error NEXT_CONSUL_VERSION is required) +ifndef CONSUL_K8S_NEXT_CONSUL_DATAPLANE_VERSION + $(error CONSUL_K8S_NEXT_CONSUL_DATAPLANE_VERSION is required) endif - source $(CURDIR)/control-plane/build-support/scripts/functions.sh; prepare_dev $(CURDIR) $(RELEASE_VERSION) "$(RELEASE_DATE)" "" $(NEXT_RELEASE_VERSION) $(NEXT_CONSUL_VERSION) + source $(CURDIR)/control-plane/build-support/scripts/functions.sh; prepare_dev $(CURDIR) $(CONSUL_K8S_RELEASE_VERSION) "$(CONSUL_K8S_RELEASE_DATE)" "" $(CONSUL_K8S_NEXT_RELEASE_VERSION) $(CONSUL_K8S_NEXT_CONSUL_VERSION) $(CONSUL_K8S_NEXT_CONSUL_DATAPLANE_VERSION) # ===========> Makefile config diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index b5f8437d83..12c45ac958 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -608,7 +608,7 @@ global: # The name (and tag) of the consul-dataplane Docker image used for the # connect-injected sidecar proxies and mesh, terminating, and ingress gateways. # @default: hashicorp/consul-dataplane: - imageConsulDataplane: "docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.3-dev" + imageConsulDataplane: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.3-dev # Configuration for running this Helm chart on the Red Hat OpenShift platform. # This Helm chart currently supports OpenShift v4.x+. diff --git a/control-plane/build-support/functions/10-util.sh b/control-plane/build-support/functions/10-util.sh index 72ce91720c..3bc87124d9 100644 --- a/control-plane/build-support/functions/10-util.sh +++ b/control-plane/build-support/functions/10-util.sh @@ -599,6 +599,8 @@ function update_version_helm { # $4 - Image base path # $5 - Consul version string # $6 - Consul image base path + # $7 - Consul-Dataplane version string + # $8 - Consul-Dataplane base path # # Returns: # 0 - success @@ -620,19 +622,32 @@ function update_version_helm { local prerelease="$3" local full_version="$2" local full_consul_version="$5" - if ! test -z "$3"; then + local full_consul_dataplane_version="$7" + local consul_dataplane_base_path="$8" + if ! test -z "$3" && test "$3" != "dev"; then + full_version="$2-$3" + full_consul_version="$5-$3" + full_consul_dataplane_version="$7-$3" + elif test "$3" == "dev"; then full_version="$2-$3" # strip off the last minor patch version so that the consul image can be set to something like 1.16-dev. The image # is produced by Consul every night full_consul_version="${5%.*}-$3" + full_consul_dataplane_version="${7%.*}-$3" fi sed_i ${SED_EXT} -e "s/(imageK8S:.*\/consul-k8s-control-plane:)[^\"]*/imageK8S: $4${full_version}/g" "${vfile}" sed_i ${SED_EXT} -e "s/(version:[[:space:]]*)[^\"]*/\1${full_version}/g" "${cfile}" sed_i ${SED_EXT} -e "s/(appVersion:[[:space:]]*)[^\"]*/\1${full_consul_version}/g" "${cfile}" sed_i ${SED_EXT} -e "s/(image:.*\/consul-k8s-control-plane:)[^\"]*/image: $4${full_version}/g" "${cfile}" - sed_i ${SED_EXT} -e "s/(image:.*\/consul:)[^\"]*/image: $6:${full_consul_version}/g" "${cfile}" - sed_i ${SED_EXT} -e "s/(image:.*\/consul:)[^\"]*/image: $6:${full_consul_version}/g" "${vfile}" + + sed_i ${SED_EXT} -e "s,^( *image:)(.*/consul:)[^\"]*\$,\1 $6:${full_consul_version},g" ${cfile} + sed_i ${SED_EXT} -e "s,^( *image:)(.*/consul:)[^\"]*\$,\1 $6:${full_consul_version},g" ${vfile} + sed_i ${SED_EXT} -e "s,^( *image:)(.*/consul-enterprise:)[^\"]*\$,\1 $6:${full_consul_version},g" ${cfile} + sed_i ${SED_EXT} -e "s,^( *image:)(.*/consul-enterprise:)[^\"]*\$,\1 $6:${full_consul_version},g" ${vfile} + + sed_i ${SED_EXT} -e "s/(imageConsulDataplane:.*\/consul-dataplane:)[^\"]*/imageConsulDataplane: ${consul_dataplane_base_path}:${full_consul_dataplane_version}/g" "${vfile}" + sed_i ${SED_EXT} -e "s,^( *image:)(.*/consul-dataplane:)[^\"]*\$,\1 ${consul_dataplane_base_path}:${full_consul_dataplane_version},g" ${cfile} if test -z "$3"; then sed_i ${SED_EXT} -e "s/(artifacthub.io\/prerelease:[[:space:]]*)[^\"]*/\1false/g" "${cfile}" @@ -651,6 +666,8 @@ function set_version { # $5 - The consul-k8s helm docker image base path # $6 - The consul version # $7 - The consul helm docker image base path + # $8 - The consul dataplane version + # $9 - The consul-dataplane helm docker image base path # # # Returns: @@ -670,6 +687,7 @@ function set_version { local sdir="$1" local vers="$2" local consul_vers="$6" + local consul_dataplane_vers="$8" status_stage "==> Updating control-plane version/version.go with version info: ${vers} "$4"" if ! update_version "${sdir}/control-plane/version/version.go" "${vers}" "$4"; then @@ -681,8 +699,8 @@ function set_version { return 1 fi - status_stage "==> Updating Helm chart version, consul-k8s: ${vers} "$4" consul: ${consul_vers} "$4"" - if ! update_version_helm "${sdir}/charts/consul" "${vers}" "$4" "$5" "${consul_vers}" "$7"; then + status_stage "==> Updating Helm chart version, consul-k8s: ${vers} "$4" consul: ${consul_vers} "$4" consul-dataplane: ${consul_dataplane_vers} "$4"" + if ! update_version_helm "${sdir}/charts/consul" "${vers}" "$4" "$5" "${consul_vers}" "$7" "${consul_dataplane_vers}" "$9"; then return 1 fi @@ -695,6 +713,7 @@ function set_changelog { # $2 - Version # $3 - Release Date # $4 - The last git release tag + # $5 - Pre-release version # # # Returns: @@ -714,20 +733,21 @@ function set_changelog { rel_date="$3" fi local last_release_date_git_tag=$4 + local preReleaseVersion="-$5" if test -z "${version}"; then err "ERROR: Must specify a version to put into the changelog" return 1 fi - if [ -z "$LAST_RELEASE_GIT_TAG" ]; then - echo "Error: LAST_RELEASE_GIT_TAG not specified." + if [ -z "$CONSUL_K8S_LAST_RELEASE_GIT_TAG" ]; then + echo "Error: CONSUL_K8S_LAST_RELEASE_GIT_TAG not specified." exit 1 fi cat <tmp && mv tmp "${curdir}"/CHANGELOG.MD -## ${version} (${rel_date}) -$(changelog-build -last-release ${LAST_RELEASE_GIT_TAG} \ +## ${version}${preReleaseVersion} (${rel_date}) +$(changelog-build -last-release ${CONSUL_K8S_LAST_RELEASE_GIT_TAG} \ -entries-dir .changelog/ \ -changelog-template .changelog/changelog.tmpl \ -note-template .changelog/note.tmpl \ @@ -742,17 +762,26 @@ function prepare_release { # $2 - The version of the release # $3 - The release date # $4 - The last release git tag for this branch (eg. v1.1.0) - # $5 - The pre-release version - # $6 - The consul version + # $5 - The consul version + # $6 - The consul-dataplane version + # $7 - The pre-release version # # # Returns: # 0 - success # * - error - echo "prepare_release: dir:$1 consul-k8s:$2 consul:$5 date:"$3" git tag:$4" - set_version "$1" "$2" "$3" "$6" "hashicorp\/consul-k8s-control-plane:" "$5" "hashicorp\/consul" - set_changelog "$1" "$2" "$3" "$4" + local curDir=$1 + local version=$2 + local releaseDate=$3 + local lastGitTag=$4 + local consulVersion=$5 + local consulDataplaneVersion=$6 + local prereleaseVersion=$7 + + echo "prepare_release: dir:${curDir} consul-k8s:${version} consul:${consulVersion} consul-dataplane:${consulDataplaneVersion} date:"${releaseDate}" git tag:${lastGitTag}" + set_version "${curDir}" "${version}" "${releaseDate}" "${prereleaseVersion}" "hashicorp\/consul-k8s-control-plane:" "${consulVersion}" "hashicorp\/consul" "${consulDataplaneVersion}" "hashicorp\/consul-dataplane" + set_changelog "${curDir}" "${version}" "${releaseDate}" "${lastGitTag}" "${prereleaseVersion}" } function prepare_dev { @@ -763,13 +792,21 @@ function prepare_dev { # $4 - The last release git tag for this branch (eg. v1.1.0) (Unused) # $5 - The version of the next release # $6 - The version of the next consul release + # $7 - The next consul-dataplane version # # Returns: # 0 - success # * - error - echo "prepare_dev: dir:$1 consul-k8s:$5 consul:$6 date:"$3" mode:dev" - set_version "$1" "$5" "$3" "dev" "docker.mirror.hashicorp.services\/hashicorppreview\/consul-k8s-control-plane:" "$6" "docker.mirror.hashicorp.services\/hashicorppreview\/consul" + local curDir=$1 + local version=$2 + local releaseDate=$3 + local nextReleaseVersion=$5 + local nextConsulVersion=$6 + local nextConsulDataplaneVersion=$7 + + echo "prepare_dev: dir:${curDir} consul-k8s:${nextReleaseVersion} consul:${nextConsulVersion} date:"${releaseDate}" mode:dev" + set_version "${curDir}" "${nextReleaseVersion}" "${releaseDate}" "dev" "docker.mirror.hashicorp.services\/hashicorppreview\/consul-k8s-control-plane:" "${nextConsulVersion}" "docker.mirror.hashicorp.services\/hashicorppreview\/consul" "${nextConsulDataplaneVersion}" "docker.mirror.hashicorp.services\/hashicorppreview\/consul-dataplane" return 0 } @@ -896,7 +933,7 @@ function ui_version { return 1 fi - local ui_version=$(sed -n ${SED_EXT} -e 's/.*CONSUL_VERSION%22%3A%22([^%]*)%22%2C%22.*/\1/p' <"$1") || return 1 + local ui_version=$(sed -n ${SED_EXT} -e 's/.*CONSUL_K8S_CONSUL_VERSION%22%3A%22([^%]*)%22%2C%22.*/\1/p' <"$1") || return 1 echo "$ui_version" return 0 } From df0e649e95caf9bd9ccf911d7e810c1dd781fa81 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Wed, 12 Jul 2023 14:42:51 -0700 Subject: [PATCH 070/120] added missing changelogs (#2565) * added missing changelogs * Update CHANGELOG.md for 0.49.8 --------- Co-authored-by: Curt Bushko --- CHANGELOG.md | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 445e0f1816..54bdba549b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,116 @@ +## 0.49.8 (July 12, 2023) + +IMPROVEMENTS: + +* helm: Add `connectInject.prepareDataplanesUpgrade` setting for help upgrading to dataplanes. This setting is required if upgrading from non-dataplanes to dataplanes when ACLs are enabled. See https://developer.hashicorp.com/consul/docs/k8s/upgrade#upgrading-to-consul-dataplane for more information. [[GH-2514](https://github.com/hashicorp/consul-k8s/issues/2514)] + +## 1.2.0 (June 28, 2023) + +FEATURES: + +* Add support for configuring Consul server-side rate limiting [[GH-2166](https://github.com/hashicorp/consul-k8s/issues/2166)] +* api-gateway: Add API Gateway for Consul on Kubernetes leveraging Consul native API Gateway configuration. [[GH-2152](https://github.com/hashicorp/consul-k8s/issues/2152)] +* crd: Add `mutualTLSMode` to the ProxyDefaults and ServiceDefaults CRDs and `allowEnablingPermissiveMutualTLS` to the Mesh CRD to support configuring permissive mutual TLS. [[GH-2100](https://github.com/hashicorp/consul-k8s/issues/2100)] +* helm: Add `JWTProvider` CRD for configuring the `jwt-provider` config entry. [[GH-2209](https://github.com/hashicorp/consul-k8s/issues/2209)] +* helm: Update the ServiceIntentions CRD to support `JWT` fields. [[GH-2213](https://github.com/hashicorp/consul-k8s/issues/2213)] + +IMPROVEMENTS: + +* cli: update minimum go version for project to 1.20. [[GH-2102](https://github.com/hashicorp/consul-k8s/issues/2102)] +* control-plane: add FIPS support [[GH-2165](https://github.com/hashicorp/consul-k8s/issues/2165)] +* control-plane: server ACL Init always appends both, the secrets from the serviceAccount's secretRefs and the one created by the Helm chart, to support Openshift secret handling. [[GH-1770](https://github.com/hashicorp/consul-k8s/issues/1770)] +* control-plane: set agent localities on Consul servers to the server node's `topology.kubernetes.io/region` label. [[GH-2093](https://github.com/hashicorp/consul-k8s/issues/2093)] +* control-plane: update alpine to 3.17 in the Docker image. [[GH-1934](https://github.com/hashicorp/consul-k8s/issues/1934)] +* control-plane: update minimum go version for project to 1.20. [[GH-2102](https://github.com/hashicorp/consul-k8s/issues/2102)] +* helm: Kubernetes v1.27 is now supported. Minimum tested version of Kubernetes is now v1.24. [[GH-2304](https://github.com/hashicorp/consul-k8s/issues/2304)] +* helm: Update the default amount of memory used by the connect-inject controller so that its less likely to get OOM killed. [[GH-2249](https://github.com/hashicorp/consul-k8s/issues/2249)] +* helm: add failover policy field to service resolver and proxy default CRDs [[GH-2030](https://github.com/hashicorp/consul-k8s/issues/2030)] +* helm: add samenessGroup CRD [[GH-2048](https://github.com/hashicorp/consul-k8s/issues/2048)] +* helm: add samenessGroup field to exported services CRD [[GH-2075](https://github.com/hashicorp/consul-k8s/issues/2075)] +* helm: add samenessGroup field to service resolver CRD [[GH-2086](https://github.com/hashicorp/consul-k8s/issues/2086)] +* helm: add samenessGroup field to source intention CRD [[GH-2097](https://github.com/hashicorp/consul-k8s/issues/2097)] +* helm: update `imageConsulDataplane` value to `hashicorp/consul-dataplane:1.1.0`. [[GH-1953](https://github.com/hashicorp/consul-k8s/issues/1953)] + +SECURITY: + +* Update [Go-Discover](https://github.com/hashicorp/go-discover) in the container has been updated to address [CVE-2020-14040](https://github.com/advisories/GHSA-5rcv-m4m3-hfh7) [[GH-2390](https://github.com/hashicorp/consul-k8s/issues/2390)] +* Bump Dockerfile base image to `alpine:3.18`. Resolves [CVE-2023-2650](https://github.com/advisories/GHSA-gqxg-9vfr-p9cg) vulnerability in openssl@3.0.8-r4 [[GH-2284](https://github.com/hashicorp/consul-k8s/issues/2284)] +* Fix Prometheus CVEs by bumping controller-runtime. [[GH-2183](https://github.com/hashicorp/consul-k8s/issues/2183)] +* Upgrade to use Go 1.20.4. + This resolves vulnerabilities [CVE-2023-24537](https://github.com/advisories/GHSA-9f7g-gqwh-jpf5)(`go/scanner`), + [CVE-2023-24538](https://github.com/advisories/GHSA-v4m2-x4rp-hv22)(`html/template`), + [CVE-2023-24534](https://github.com/advisories/GHSA-8v5j-pwr7-w5f8)(`net/textproto`) and + [CVE-2023-24536](https://github.com/advisories/GHSA-9f7g-gqwh-jpf5)(`mime/multipart`). + Also, `golang.org/x/net` has been updated to v0.7.0 to resolve CVEs [CVE-2022-41721 + ](https://github.com/advisories/GHSA-fxg5-wq6x-vr4w + ), [CVE-2022-27664](https://github.com/advisories/GHSA-69cg-p879-7622) and [CVE-2022-41723 + ](https://github.com/advisories/GHSA-vvpx-j8f3-3w6h + .) [[GH-2102](https://github.com/hashicorp/consul-k8s/issues/2102)] + +BUG FIXES: + +* control-plane: Fix casing of the Enforce Consecutive 5xx field on Service Defaults and acceptance test fixtures. [[GH-2266](https://github.com/hashicorp/consul-k8s/issues/2266)] +* control-plane: fix issue where consul-connect-injector acl token was unintentionally being deleted and not recreated when a container was restarted due to a livenessProbe failure. [[GH-1914](https://github.com/hashicorp/consul-k8s/issues/1914)] + +## 1.1.3 (June 28, 2023) +BREAKING CHANGES: + +* control-plane: All policies managed by consul-k8s will now be updated on upgrade. If you previously edited the policies after install, your changes will be overwritten. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] + +SECURITY: + +* Bump Dockerfile base image to `alpine:3.18`. Resolves [CVE-2023-2650](https://github.com/advisories/GHSA-gqxg-9vfr-p9cg) vulnerability in openssl@3.0.8-r4 [[GH-2284](https://github.com/hashicorp/consul-k8s/issues/2284)] +* Update [Go-Discover](https://github.com/hashicorp/go-discover) in the container has been updated to address [CVE-2020-14040](https://github.com/advisories/GHSA-5rcv-m4m3-hfh7) [[GH-2390](https://github.com/hashicorp/consul-k8s/issues/2390)] + +FEATURES: + +* Add support for configuring graceful shutdown proxy lifecycle management settings. [[GH-2233](https://github.com/hashicorp/consul-k8s/issues/2233)] +* helm: Adds `acls.resources` field which can be configured to override the `resource` settings for the `server-acl-init` and `server-acl-init-cleanup` Jobs. [[GH-2416](https://github.com/hashicorp/consul-k8s/issues/2416)] +* sync-catalog: add ability to support weighted loadbalancing by service annotation `consul.hashicorp.com/service-weight: ` [[GH-2293](https://github.com/hashicorp/consul-k8s/issues/2293)] + +IMPROVEMENTS: + +* (Consul Enterprise) Add support to provide inputs via helm for audit log related configuration [[GH-2369](https://github.com/hashicorp/consul-k8s/issues/2369)] +* helm: Update the default amount of memory used by the connect-inject controller so that its less likely to get OOM killed. [[GH-2249](https://github.com/hashicorp/consul-k8s/issues/2249)] + +BUG FIXES: + +* control-plane: Always update ACL policies upon upgrade. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] +* control-plane: Fix casing of the Enforce Consecutive 5xx field on Service Defaults and acceptance test fixtures. [[GH-2266](https://github.com/hashicorp/consul-k8s/issues/2266)] + +## 1.0.8 (June 28, 2023) +BREAKING CHANGES: + +* control-plane: All policies managed by consul-k8s will now be updated on upgrade. If you previously edited the policies after install, your changes will be overwritten. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] + +SECURITY: + +* Bump Dockerfile base image for RedHat UBI `consul-k8s-control-plane` image to `ubi-minimal:9.2`. [[GH-2204](https://github.com/hashicorp/consul-k8s/issues/2204)] +* Bump Dockerfile base image to `alpine:3.18`. Resolves [CVE-2023-2650](https://github.com/advisories/GHSA-gqxg-9vfr-p9cg) vulnerability in openssl@3.0.8-r4 [[GH-2284](https://github.com/hashicorp/consul-k8s/issues/2284)] +* Bump `controller-runtime` to address CVEs in dependencies. [[GH-2225](https://github.com/hashicorp/consul-k8s/issues/2225)] +* Update [Go-Discover](https://github.com/hashicorp/go-discover) in the container has been updated to address [CVE-2020-14040](https://github.com/advisories/GHSA-5rcv-m4m3-hfh7) [[GH-2390](https://github.com/hashicorp/consul-k8s/issues/2390)] + +FEATURES: + +* Add support for configuring graceful shutdown proxy lifecycle management settings. [[GH-2233](https://github.com/hashicorp/consul-k8s/issues/2233)] +* helm: Adds `acls.resources` field which can be configured to override the `resource` settings for the `server-acl-init` and `server-acl-init-cleanup` Jobs. [[GH-2416](https://github.com/hashicorp/consul-k8s/issues/2416)] +* sync-catalog: add ability to support weighted loadbalancing by service annotation `consul.hashicorp.com/service-weight: ` [[GH-2293](https://github.com/hashicorp/consul-k8s/issues/2293)] + +IMPROVEMENTS: + +* (Consul Enterprise) Add support to provide inputs via helm for audit log related configuration [[GH-2265](https://github.com/hashicorp/consul-k8s/issues/2265)] +* helm: Update the default amount of memory used by the connect-inject controller so that its less likely to get OOM killed. [[GH-2249](https://github.com/hashicorp/consul-k8s/issues/2249)] + +BUG FIXES: + +* control-plane: Always update ACL policies upon upgrade. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] +* control-plane: Fix casing of the Enforce Consecutive 5xx field on Service Defaults and acceptance test fixtures. [[GH-2266](https://github.com/hashicorp/consul-k8s/issues/2266)] +* control-plane: add support for idleTimeout in the Service Router config [[GH-2156](https://github.com/hashicorp/consul-k8s/issues/2156)] +* control-plane: fix issue with json tags of service defaults fields EnforcingConsecutive5xx, MaxEjectionPercent and BaseEjectionTime. [[GH-2159](https://github.com/hashicorp/consul-k8s/issues/2159)] +* control-plane: fix issue with multiport pods crashlooping due to dataplane port conflicts by ensuring dns redirection is disabled for non-tproxy pods [[GH-2176](https://github.com/hashicorp/consul-k8s/issues/2176)] +* crd: fix bug on service intentions CRD causing some updates to be ignored. [[GH-2194](https://github.com/hashicorp/consul-k8s/issues/2194)] + + ## 0.49.7 (June 28, 2023) BREAKING CHANGES: From 29b6ed36923498afc8f377455d4275653960230f Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Fri, 14 Jul 2023 13:42:05 -0700 Subject: [PATCH 071/120] Refactor test framework to allow for more than two kube contexts (#2534) * updated contributing example with new configuration lists add new make target "kind" to makefile * This lets us setup our standard kind environment for testing refactor framework to take config list flags * removed primary/secondary kube flags as this limited us to only two clusters * added flags for kube configs, contexts and namespaces. This way we can support n clusters where n is the length of the longest list. The flags are then combined into a list of objects for use in testing added tests for new helper methods refactored tests * now TestMain for multicluster check that the test arguments contain the expected number of clusters * use helper method `env.GetSecondaryContextKey(t)` which grabs the second context in the list instead of using the defunct environment.SecondaryContextName refactored flag test to use new config lists refactored cli cluster to use get primary helper added multicluster check for vault acceptance * vault tests are multi-cluster but we weren't performing the necessary checks --- CONTRIBUTING.md | 21 ++-- Makefile | 29 +++-- acceptance/framework/config/config.go | 64 +++++++++-- acceptance/framework/config/config_test.go | 103 ++++++++++++++++++ acceptance/framework/consul/cli_cluster.go | 7 +- .../framework/environment/environment.go | 47 +++----- acceptance/framework/flags/flags.go | 82 ++++++++------ acceptance/framework/flags/flags_test.go | 97 ++++++++++++----- acceptance/tests/partitions/main_test.go | 6 +- .../partitions/partitions_connect_test.go | 3 +- .../partitions/partitions_gateway_test.go | 3 +- .../tests/partitions/partitions_sync_test.go | 3 +- acceptance/tests/peering/main_test.go | 6 +- .../peering_connect_namespaces_test.go | 3 +- .../tests/peering/peering_connect_test.go | 3 +- .../tests/peering/peering_gateway_test.go | 3 +- acceptance/tests/vault/main_test.go | 11 +- .../tests/vault/vault_partitions_test.go | 3 +- acceptance/tests/vault/vault_wan_fed_test.go | 2 +- acceptance/tests/wan-federation/main_test.go | 6 +- .../wan_federation_gateway_test.go | 2 +- .../wan-federation/wan_federation_test.go | 3 +- 22 files changed, 357 insertions(+), 150 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f0deb97ce9..c1e3446e8d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -642,8 +642,7 @@ you may use the following command: go test ./... -p 1 -timeout 20m \ -enable-multi-cluster \ - -kubecontext= \ - -secondary-kubecontext= + -kube-contexts=",, etc.>" Below is the list of available flags: @@ -667,20 +666,14 @@ Below is the list of available flags: This applies only to tests that enable connectInject. -enterprise-license The enterprise license for Consul. --kubeconfig string - The path to a kubeconfig file. If this is blank, the default kubeconfig path (~/.kube/config) will be used. --kubecontext string - The name of the Kubernetes context to use. If this is blank, the context set as the current context will be used by default. --namespace string - The Kubernetes namespace to use for tests. (default "default") +-kubeconfigs string + The comma separated list of Kubernetes configs to use (eg. "~/.kube/config,~/.kube/config2"). The first in the list will be treated as the primary config, followed by the secondary, etc. If the list is empty, or items are blank, then the default kubeconfig path (~/.kube/config) will be used. +-kube-contexts string + The comma separated list of Kubernetes contexts to use (eg. "kind-dc1,kind-dc2"). The first in the list will be treated as the primary context, followed by the secondary, etc. If the list is empty, or items are blank, then the current context will be used. +-kube-namespaces string + The comma separated list of Kubernetes namespaces to use (eg. "consul,consul-secondary"). The first in the list will be treated as the primary namespace, followed by the secondary, etc. If the list is empty, or fields are blank, then the current namespace will be used. -no-cleanup-on-failure If true, the tests will not cleanup Kubernetes resources they create when they finish running.Note this flag must be run with -failfast flag, otherwise subsequent tests will fail. --secondary-kubeconfig string - The path to a kubeconfig file of the secondary k8s cluster. If this is blank, the default kubeconfig path (~/.kube/config) will be used. --secondary-kubecontext string - The name of the Kubernetes context for the secondary cluster to use. If this is blank, the context set as the current context will be used by default. --secondary-namespace string - The Kubernetes namespace to use in the secondary k8s cluster. (default "default") ``` **Note:** There is a Terraform configuration in the diff --git a/Makefile b/Makefile index 1b7e4d8d7b..1d62035dbb 100644 --- a/Makefile +++ b/Makefile @@ -87,15 +87,6 @@ cni-plugin-lint: ctrl-generate: get-controller-gen ## Run CRD code generation. cd control-plane; $(CONTROLLER_GEN) object paths="./..." -# Helper target for doing local cni acceptance testing -kind-cni: - kind delete cluster --name dc1 - kind delete cluster --name dc2 - kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc1 --image kindest/node:v1.23.6 - make kind-cni-calico - kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc2 --image kindest/node:v1.23.6 - make kind-cni-calico - # Perform a terraform fmt check but don't change anything terraform-fmt-check: @$(CURDIR)/control-plane/build-support/scripts/terraformfmtcheck.sh $(TERRAFORM_DIR) @@ -133,7 +124,24 @@ kind-cni-calico: # Sleeps are needed as installs can happen too quickly for Kind to handle it @sleep 30 kubectl create -f $(CURDIR)/acceptance/framework/environment/cni-kind/custom-resources.yaml - @sleep 20 + @sleep 20 + +# Helper target for doing local cni acceptance testing +kind-cni: + kind delete cluster --name dc1 + kind delete cluster --name dc2 + kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc1 --image $(KIND_NODE_IMAGE) + make kind-cni-calico + kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc2 --image $(KIND_NODE_IMAGE) + make kind-cni-calico + +# Helper target for doing local acceptance testing +kind: + kind delete cluster --name dc1 + kind delete cluster --name dc2 + kind create cluster --name dc1 --image $(KIND_NODE_IMAGE) + kind create cluster --name dc2 --image $(KIND_NODE_IMAGE) + # ===========> Shared Targets @@ -247,7 +255,6 @@ endif source $(CURDIR)/control-plane/build-support/scripts/functions.sh; prepare_dev $(CURDIR) $(CONSUL_K8S_RELEASE_VERSION) "$(CONSUL_K8S_RELEASE_DATE)" "" $(CONSUL_K8S_NEXT_RELEASE_VERSION) $(CONSUL_K8S_NEXT_CONSUL_VERSION) $(CONSUL_K8S_NEXT_CONSUL_DATAPLANE_VERSION) # ===========> Makefile config - .DEFAULT_GOAL := help .PHONY: gen-helm-docs copy-crds-to-chart generate-external-crds bats-tests help ci.aws-acceptance-test-cleanup version cli-dev prepare-dev prepare-release SHELL = bash diff --git a/acceptance/framework/config/config.go b/acceptance/framework/config/config.go index 7151a75908..eada42af20 100644 --- a/acceptance/framework/config/config.go +++ b/acceptance/framework/config/config.go @@ -5,6 +5,7 @@ package config import ( "fmt" + "math" "os" "path/filepath" "strconv" @@ -22,16 +23,48 @@ const ( LicenseSecretKey = "key" ) -// TestConfig holds configuration for the test suite. -type TestConfig struct { - Kubeconfig string +type KubeTestConfig struct { + KubeConfig string KubeContext string KubeNamespace string +} + +// NewKubeTestConfigList takes lists of kubernetes configs, contexts and namespaces and constructs KubeTestConfig +// We validate ahead of time that the lists are either 0 or the same length as we expect that if the length of a list +// is greater than 0, then the indexes should match. For example: []kubeContexts{"ctx1", "ctx2"} indexes 0, 1 match with []kubeNamespaces{"ns1", "ns2"}. +func NewKubeTestConfigList(kubeConfigs, kubeContexts, kubeNamespaces []string) []KubeTestConfig { + // Grab the longest length. + l := math.Max(float64(len(kubeConfigs)), + math.Max(float64(len(kubeContexts)), float64(len(kubeNamespaces)))) + + // If all are empty, then return a single empty entry + if l == 0 { + return []KubeTestConfig{{}} + } + + // Add each non-zero length list to the new structs, we should have + // n structs where n == l. + out := make([]KubeTestConfig, int(l)) + for i := range out { + kenv := KubeTestConfig{} + if len(kubeConfigs) != 0 { + kenv.KubeConfig = kubeConfigs[i] + } + if len(kubeContexts) != 0 { + kenv.KubeContext = kubeContexts[i] + } + if len(kubeNamespaces) != 0 { + kenv.KubeNamespace = kubeNamespaces[i] + } + out[i] = kenv + } + return out +} - EnableMultiCluster bool - SecondaryKubeconfig string - SecondaryKubeContext string - SecondaryKubeNamespace string +// TestConfig holds configuration for the test suite. +type TestConfig struct { + KubeEnvs []KubeTestConfig + EnableMultiCluster bool EnableEnterprise bool EnterpriseLicense string @@ -117,6 +150,23 @@ func (t *TestConfig) HelmValuesFromConfig() (map[string]string, error) { return helmValues, nil } +// IsExpectedClusterCount check that we have at least the required number of clusters to +// run a test. +func (t *TestConfig) IsExpectedClusterCount(count int) bool { + return len(t.KubeEnvs) >= count +} + +// GetPrimaryKubeEnv returns the primary Kubernetes environment. +func (t *TestConfig) GetPrimaryKubeEnv() KubeTestConfig { + // Return the first in the list as this is always the primary + // kube environment. If empty return an empty kubeEnv + if len(t.KubeEnvs) < 1 { + return KubeTestConfig{} + } else { + return t.KubeEnvs[0] + } +} + type values struct { Global globalValues `yaml:"global"` } diff --git a/acceptance/framework/config/config_test.go b/acceptance/framework/config/config_test.go index f5992cdd99..96f0f0e7eb 100644 --- a/acceptance/framework/config/config_test.go +++ b/acceptance/framework/config/config_test.go @@ -181,3 +181,106 @@ func TestConfig_HelmValuesFromConfig_EntImage(t *testing.T) { }) } } + +func Test_KubeEnvListFromStringList(t *testing.T) { + tests := []struct { + name string + kubeContexts []string + KubeConfigs []string + kubeNamespaces []string + expKubeEnvList []KubeTestConfig + }{ + { + name: "empty-lists", + kubeContexts: []string{}, + KubeConfigs: []string{}, + kubeNamespaces: []string{}, + expKubeEnvList: []KubeTestConfig{{}}, + }, + { + name: "kubeContext set", + kubeContexts: []string{"ctx1", "ctx2"}, + KubeConfigs: []string{}, + kubeNamespaces: []string{}, + expKubeEnvList: []KubeTestConfig{{KubeContext: "ctx1"}, {KubeContext: "ctx2"}}, + }, + { + name: "kubeNamespace set", + kubeContexts: []string{}, + KubeConfigs: []string{"/path/config1", "/path/config2"}, + kubeNamespaces: []string{}, + expKubeEnvList: []KubeTestConfig{{KubeConfig: "/path/config1"}, {KubeConfig: "/path/config2"}}, + }, + { + name: "kubeConfigs set", + kubeContexts: []string{}, + KubeConfigs: []string{}, + kubeNamespaces: []string{"ns1", "ns2"}, + expKubeEnvList: []KubeTestConfig{{KubeNamespace: "ns1"}, {KubeNamespace: "ns2"}}, + }, + { + name: "multiple everything", + kubeContexts: []string{"ctx1", "ctx2"}, + KubeConfigs: []string{"/path/config1", "/path/config2"}, + kubeNamespaces: []string{"ns1", "ns2"}, + expKubeEnvList: []KubeTestConfig{{KubeContext: "ctx1", KubeNamespace: "ns1", KubeConfig: "/path/config1"}, {KubeContext: "ctx2", KubeNamespace: "ns2", KubeConfig: "/path/config2"}}, + }, + { + name: "multiple context and configs", + kubeContexts: []string{"ctx1", "ctx2"}, + KubeConfigs: []string{"/path/config1", "/path/config2"}, + kubeNamespaces: []string{}, + expKubeEnvList: []KubeTestConfig{{KubeContext: "ctx1", KubeConfig: "/path/config1"}, {KubeContext: "ctx2", KubeConfig: "/path/config2"}}, + }, + { + name: "multiple namespace and configs", + kubeContexts: []string{}, + KubeConfigs: []string{"/path/config1", "/path/config2"}, + kubeNamespaces: []string{"ns1", "ns2"}, + expKubeEnvList: []KubeTestConfig{{KubeNamespace: "ns1", KubeConfig: "/path/config1"}, {KubeNamespace: "ns2", KubeConfig: "/path/config2"}}, + }, + { + name: "multiple context and namespace", + kubeContexts: []string{"ctx1", "ctx2"}, + KubeConfigs: []string{}, + kubeNamespaces: []string{"ns1", "ns2"}, + expKubeEnvList: []KubeTestConfig{{KubeContext: "ctx1", KubeNamespace: "ns1"}, {KubeContext: "ctx2", KubeNamespace: "ns2"}}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := NewKubeTestConfigList(tt.KubeConfigs, tt.kubeContexts, tt.kubeNamespaces) + require.Equal(t, tt.expKubeEnvList, actual) + }) + } +} + +func Test_GetPrimaryKubeEnv(t *testing.T) { + tests := []struct { + name string + kubeEnvList []KubeTestConfig + expPrimaryKubeEnv KubeTestConfig + }{ + { + name: "context config multiple namespace single", + kubeEnvList: []KubeTestConfig{{KubeContext: "ctx1", KubeNamespace: "ns1", KubeConfig: "/path/config1"}, {KubeContext: "ctx2", KubeConfig: "/path/config2"}}, + expPrimaryKubeEnv: KubeTestConfig{KubeContext: "ctx1", KubeNamespace: "ns1", KubeConfig: "/path/config1"}, + }, + { + name: "context config multiple namespace single", + kubeEnvList: []KubeTestConfig{}, + expPrimaryKubeEnv: KubeTestConfig{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cfg := TestConfig{ + KubeEnvs: tt.kubeEnvList, + } + actual := cfg.GetPrimaryKubeEnv() + require.Equal(t, tt.expPrimaryKubeEnv, actual) + }) + } +} diff --git a/acceptance/framework/consul/cli_cluster.go b/acceptance/framework/consul/cli_cluster.go index ba4cfc93ab..9e119af76d 100644 --- a/acceptance/framework/consul/cli_cluster.go +++ b/acceptance/framework/consul/cli_cluster.go @@ -97,16 +97,17 @@ func NewCLICluster( cli, err := cli.NewCLI() require.NoError(t, err) + require.Greater(t, len(cfg.KubeEnvs), 0) return &CLICluster{ ctx: ctx, helmOptions: hopts, kubectlOptions: kopts, - namespace: cfg.KubeNamespace, + namespace: cfg.GetPrimaryKubeEnv().KubeNamespace, values: values, releaseName: releaseName, kubernetesClient: ctx.KubernetesClient(t), - kubeConfig: cfg.Kubeconfig, - kubeContext: cfg.KubeContext, + kubeConfig: cfg.GetPrimaryKubeEnv().KubeConfig, + kubeContext: cfg.GetPrimaryKubeEnv().KubeContext, noCleanupOnFailure: cfg.NoCleanupOnFailure, debugDirectory: cfg.DebugDirectory, logger: logger, diff --git a/acceptance/framework/environment/environment.go b/acceptance/framework/environment/environment.go index 58e4e83a5b..9150f4ff03 100644 --- a/acceptance/framework/environment/environment.go +++ b/acceptance/framework/environment/environment.go @@ -21,15 +21,14 @@ import ( ) const ( - DefaultContextName = "default" - SecondaryContextName = "secondary" + DefaultContextIndex = 0 ) // TestEnvironment represents the infrastructure environment of the test, // such as the kubernetes cluster(s) the test is running against. type TestEnvironment interface { DefaultContext(t *testing.T) TestContext - Context(t *testing.T, name string) TestContext + Context(t *testing.T, index int) TestContext } // TestContext represents a specific context a test needs, @@ -41,50 +40,40 @@ type TestContext interface { } type KubernetesEnvironment struct { - contexts map[string]*kubernetesContext + contexts []*kubernetesContext } func NewKubernetesEnvironmentFromConfig(config *config.TestConfig) *KubernetesEnvironment { - defaultContext := NewContext(config.KubeNamespace, config.Kubeconfig, config.KubeContext) + // First kubeEnv is the default + defaultContext := NewContext(config.GetPrimaryKubeEnv().KubeNamespace, config.GetPrimaryKubeEnv().KubeConfig, config.GetPrimaryKubeEnv().KubeContext) // Create a kubernetes environment with default context. kenv := &KubernetesEnvironment{ - contexts: map[string]*kubernetesContext{ - DefaultContextName: defaultContext, + contexts: []*kubernetesContext{ + defaultContext, }, } - // Add secondary context if multi cluster tests are enabled. + // Add additional contexts if multi cluster tests are enabled. if config.EnableMultiCluster { - kenv.contexts[SecondaryContextName] = NewContext(config.SecondaryKubeNamespace, config.SecondaryKubeconfig, config.SecondaryKubeContext) - } - - return kenv -} - -func NewKubernetesEnvironmentFromContext(context *kubernetesContext) *KubernetesEnvironment { - // Create a kubernetes environment with default context. - kenv := &KubernetesEnvironment{ - contexts: map[string]*kubernetesContext{ - DefaultContextName: context, - }, + for _, v := range config.KubeEnvs[1:] { + kenv.contexts = append(kenv.contexts, NewContext(v.KubeNamespace, v.KubeConfig, v.KubeContext)) + } } return kenv } -func (k *KubernetesEnvironment) Context(t *testing.T, name string) TestContext { - ctx, ok := k.contexts[name] - require.Truef(t, ok, fmt.Sprintf("requested context %s not found", name)) - - return ctx +func (k *KubernetesEnvironment) Context(t *testing.T, index int) TestContext { + lenContexts := len(k.contexts) + require.Greater(t, lenContexts, index, fmt.Sprintf("context list does not contain an index %d, length is %d", index, lenContexts)) + return k.contexts[index] } func (k *KubernetesEnvironment) DefaultContext(t *testing.T) TestContext { - ctx, ok := k.contexts[DefaultContextName] - require.Truef(t, ok, "default context not found") - - return ctx + lenContexts := len(k.contexts) + require.Greater(t, lenContexts, DefaultContextIndex, fmt.Sprintf("context list does not contain an index %d, length is %d", DefaultContextIndex, lenContexts)) + return k.contexts[DefaultContextIndex] } type kubernetesContext struct { diff --git a/acceptance/framework/flags/flags.go b/acceptance/framework/flags/flags.go index 5df09f853a..ad36099b37 100644 --- a/acceptance/framework/flags/flags.go +++ b/acceptance/framework/flags/flags.go @@ -7,6 +7,7 @@ import ( "errors" "flag" "os" + "strings" "sync" "github.com/hashicorp/consul-k8s/acceptance/framework/config" @@ -14,14 +15,10 @@ import ( ) type TestFlags struct { - flagKubeconfig string - flagKubecontext string - flagNamespace string - - flagEnableMultiCluster bool - flagSecondaryKubeconfig string - flagSecondaryKubecontext string - flagSecondaryNamespace string + flagKubeconfigs listFlag + flagKubecontexts listFlag + flagKubeNamespaces listFlag + flagEnableMultiCluster bool flagEnableEnterprise bool flagEnterpriseLicense string @@ -68,13 +65,19 @@ func NewTestFlags() *TestFlags { return t } -func (t *TestFlags) init() { - flag.StringVar(&t.flagKubeconfig, "kubeconfig", "", "The path to a kubeconfig file. If this is blank, "+ - "the default kubeconfig path (~/.kube/config) will be used.") - flag.StringVar(&t.flagKubecontext, "kubecontext", "", "The name of the Kubernetes context to use. If this is blank, "+ - "the context set as the current context will be used by default.") - flag.StringVar(&t.flagNamespace, "namespace", "", "The Kubernetes namespace to use for tests.") +type listFlag []string +// String() returns a comma separated list in the form "var1,var2,var3". +func (f *listFlag) String() string { + return strings.Join(*f, ",") +} + +func (f *listFlag) Set(value string) error { + *f = strings.Split(value, ",") + return nil +} + +func (t *TestFlags) init() { flag.StringVar(&t.flagConsulImage, "consul-image", "", "The Consul image to use for all tests.") flag.StringVar(&t.flagConsulK8sImage, "consul-k8s-image", "", "The consul-k8s image to use for all tests.") flag.StringVar(&t.flagConsulDataplaneImage, "consul-dataplane-image", "", "The consul-dataplane image to use for all tests.") @@ -86,16 +89,16 @@ func (t *TestFlags) init() { flag.StringVar(&t.flagVaultServerVersion, "vault-server-version", "", "The vault serverversion used for all tests.") flag.StringVar(&t.flagVaultHelmChartVersion, "vault-helm-chart-version", "", "The Vault helm chart used for all tests.") + flag.Var(&t.flagKubeconfigs, "kubeconfigs", "The list of paths to a kubeconfig files. If this is blank, "+ + "the default kubeconfig path (~/.kube/config) will be used.") + flag.Var(&t.flagKubecontexts, "kube-contexts", "The list of names of the Kubernetes contexts to use. If this is blank, "+ + "the context set as the current context will be used by default.") + flag.Var(&t.flagKubeNamespaces, "kube-namespaces", "The list of Kubernetes namespaces to use for tests.") flag.StringVar(&t.flagHCPResourceID, "hcp-resource-id", "", "The hcp resource id to use for all tests.") flag.BoolVar(&t.flagEnableMultiCluster, "enable-multi-cluster", false, "If true, the tests that require multiple Kubernetes clusters will be run. "+ - "At least one of -secondary-kubeconfig or -secondary-kubecontext is required when this flag is used.") - flag.StringVar(&t.flagSecondaryKubeconfig, "secondary-kubeconfig", "", "The path to a kubeconfig file of the secondary k8s cluster. "+ - "If this is blank, the default kubeconfig path (~/.kube/config) will be used.") - flag.StringVar(&t.flagSecondaryKubecontext, "secondary-kubecontext", "", "The name of the Kubernetes context for the secondary cluster to use. "+ - "If this is blank, the context set as the current context will be used by default.") - flag.StringVar(&t.flagSecondaryNamespace, "secondary-namespace", "", "The Kubernetes namespace to use in the secondary k8s cluster.") + "The lists -kubeconfig or -kube-context must contain more than one entry when this flag is used.") flag.BoolVar(&t.flagEnableEnterprise, "enable-enterprise", false, "If true, the test suite will run tests for enterprise features. "+ @@ -143,8 +146,26 @@ func (t *TestFlags) init() { func (t *TestFlags) Validate() error { if t.flagEnableMultiCluster { - if t.flagSecondaryKubecontext == "" && t.flagSecondaryKubeconfig == "" { - return errors.New("at least one of -secondary-kubecontext or -secondary-kubeconfig flags must be provided if -enable-multi-cluster is set") + if len(t.flagKubecontexts) <= 1 && len(t.flagKubeconfigs) <= 1 { + return errors.New("at least two contexts must be included in -kube-contexts or -kubeconfigs if -enable-multi-cluster is set") + } + } + + if len(t.flagKubecontexts) != 0 && len(t.flagKubeconfigs) != 0 { + if len(t.flagKubecontexts) != len(t.flagKubeconfigs) { + return errors.New("-kube-contexts and -kubeconfigs are both set but are not of equal length") + } + } + + if len(t.flagKubecontexts) != 0 && len(t.flagKubeNamespaces) != 0 { + if len(t.flagKubecontexts) != len(t.flagKubeNamespaces) { + return errors.New("-kube-contexts and -kube-namespaces are both set but are not of equal length") + } + } + + if len(t.flagKubeNamespaces) != 0 && len(t.flagKubeconfigs) != 0 { + if len(t.flagKubeNamespaces) != len(t.flagKubeconfigs) { + return errors.New("-kube-namespaces and -kubeconfigs are both set but are not of equal length") } } @@ -161,20 +182,15 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { consulVersion, _ := version.NewVersion(t.flagConsulVersion) consulDataplaneVersion, _ := version.NewVersion(t.flagConsulDataplaneVersion) //vaultserverVersion, _ := version.NewVersion(t.flagVaultServerVersion) + kubeEnvs := config.NewKubeTestConfigList(t.flagKubeconfigs, t.flagKubecontexts, t.flagKubeNamespaces) - return &config.TestConfig{ - Kubeconfig: t.flagKubeconfig, - KubeContext: t.flagKubecontext, - KubeNamespace: t.flagNamespace, - - EnableMultiCluster: t.flagEnableMultiCluster, - SecondaryKubeconfig: t.flagSecondaryKubeconfig, - SecondaryKubeContext: t.flagSecondaryKubecontext, - SecondaryKubeNamespace: t.flagSecondaryNamespace, - + c := &config.TestConfig{ EnableEnterprise: t.flagEnableEnterprise, EnterpriseLicense: t.flagEnterpriseLicense, + KubeEnvs: kubeEnvs, + EnableMultiCluster: t.flagEnableMultiCluster, + EnableOpenshift: t.flagEnableOpenshift, EnablePodSecurityPolicies: t.flagEnablePodSecurityPolicies, @@ -205,4 +221,6 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { UseGKE: t.flagUseGKE, UseKind: t.flagUseKind, } + + return c } diff --git a/acceptance/framework/flags/flags_test.go b/acceptance/framework/flags/flags_test.go index 7546ae911c..1e2bf0a039 100644 --- a/acceptance/framework/flags/flags_test.go +++ b/acceptance/framework/flags/flags_test.go @@ -11,9 +11,10 @@ import ( func TestFlags_validate(t *testing.T) { type fields struct { - flagEnableMultiCluster bool - flagSecondaryKubeconfig string - flagSecondaryKubecontext string + flagEnableMultiCluster bool + flagKubeConfigs listFlag + flagKubeContexts listFlag + flagNamespaces listFlag flagEnableEnt bool flagEntLicense string @@ -26,20 +27,16 @@ func TestFlags_validate(t *testing.T) { }{ { "no error by default", - fields{ - flagEnableMultiCluster: false, - flagSecondaryKubeconfig: "", - flagSecondaryKubecontext: "", - }, + fields{}, false, "", }, { "enable multi cluster: no error when multi cluster is disabled", fields{ - flagEnableMultiCluster: false, - flagSecondaryKubeconfig: "", - flagSecondaryKubecontext: "", + flagEnableMultiCluster: false, + flagKubeConfigs: listFlag{}, + flagKubeContexts: listFlag{}, }, false, "", @@ -47,19 +44,19 @@ func TestFlags_validate(t *testing.T) { { "enable multi cluster: errors when both secondary kubeconfig and kubecontext are empty", fields{ - flagEnableMultiCluster: true, - flagSecondaryKubeconfig: "", - flagSecondaryKubecontext: "", + flagEnableMultiCluster: true, + flagKubeConfigs: listFlag{}, + flagKubeContexts: listFlag{}, }, true, - "at least one of -secondary-kubecontext or -secondary-kubeconfig flags must be provided if -enable-multi-cluster is set", + "at least two contexts must be included in -kube-contexts or -kubeconfigs if -enable-multi-cluster is set", }, { "enable multi cluster: no error when secondary kubeconfig but not kubecontext is provided", fields{ - flagEnableMultiCluster: true, - flagSecondaryKubeconfig: "foo", - flagSecondaryKubecontext: "", + flagEnableMultiCluster: true, + flagKubeConfigs: listFlag{"foo", "bar"}, + flagKubeContexts: listFlag{}, }, false, "", @@ -67,9 +64,9 @@ func TestFlags_validate(t *testing.T) { { "enable multi cluster: no error when secondary kubecontext but not kubeconfig is provided", fields{ - flagEnableMultiCluster: true, - flagSecondaryKubeconfig: "", - flagSecondaryKubecontext: "foo", + flagEnableMultiCluster: true, + flagKubeConfigs: listFlag{}, + flagKubeContexts: listFlag{"foo", "bar"}, }, false, "", @@ -77,13 +74,54 @@ func TestFlags_validate(t *testing.T) { { "enable multi cluster: no error when both secondary kubecontext and kubeconfig are provided", fields{ - flagEnableMultiCluster: true, - flagSecondaryKubeconfig: "foo", - flagSecondaryKubecontext: "bar", + flagEnableMultiCluster: true, + flagKubeConfigs: listFlag{"foo", "bar"}, + flagKubeContexts: listFlag{"foo", "bar"}, + }, + false, + "", + }, + { + "enable multi cluster: no error when all of secondary kubecontext, kubeconfigs and namespaces are provided", + fields{ + flagEnableMultiCluster: true, + flagKubeConfigs: listFlag{"foo", "bar"}, + flagKubeContexts: listFlag{"foo", "bar"}, + flagNamespaces: listFlag{"foo", "bar"}, }, false, "", }, + { + "enable multi cluster: error when the list of kubeconfigs and kubecontexts do not match", + fields{ + flagEnableMultiCluster: true, + flagKubeConfigs: listFlag{"foo", "bar"}, + flagKubeContexts: listFlag{"foo"}, + }, + true, + "-kube-contexts and -kubeconfigs are both set but are not of equal length", + }, + { + "enable multi cluster: error when the list of kubeconfigs and namespaces do not match", + fields{ + flagEnableMultiCluster: true, + flagKubeConfigs: listFlag{"foo", "bar"}, + flagNamespaces: listFlag{"foo"}, + }, + true, + "-kube-namespaces and -kubeconfigs are both set but are not of equal length", + }, + { + "enable multi cluster: error when the list of kubecontexts and namespaces do not match", + fields{ + flagEnableMultiCluster: true, + flagKubeContexts: listFlag{"foo", "bar"}, + flagNamespaces: listFlag{"foo"}, + }, + true, + "-kube-contexts and -kube-namespaces are both set but are not of equal length", + }, { "enterprise license: error when only -enable-enterprise is true but env CONSUL_ENT_LICENSE is not provided", fields{ @@ -105,11 +143,12 @@ func TestFlags_validate(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tf := &TestFlags{ - flagEnableMultiCluster: tt.fields.flagEnableMultiCluster, - flagSecondaryKubeconfig: tt.fields.flagSecondaryKubeconfig, - flagSecondaryKubecontext: tt.fields.flagSecondaryKubecontext, - flagEnableEnterprise: tt.fields.flagEnableEnt, - flagEnterpriseLicense: tt.fields.flagEntLicense, + flagEnableMultiCluster: tt.fields.flagEnableMultiCluster, + flagKubeconfigs: tt.fields.flagKubeConfigs, + flagKubecontexts: tt.fields.flagKubeContexts, + flagKubeNamespaces: tt.fields.flagNamespaces, + flagEnableEnterprise: tt.fields.flagEnableEnt, + flagEnterpriseLicense: tt.fields.flagEntLicense, } err := tf.Validate() if tt.wantErr { diff --git a/acceptance/tests/partitions/main_test.go b/acceptance/tests/partitions/main_test.go index 9368c12f00..89833ec2cc 100644 --- a/acceptance/tests/partitions/main_test.go +++ b/acceptance/tests/partitions/main_test.go @@ -16,10 +16,12 @@ var suite testsuite.Suite func TestMain(m *testing.M) { suite = testsuite.NewSuite(m) - if suite.Config().EnableMultiCluster { + expectedNumberOfClusters := 2 + if suite.Config().EnableMultiCluster && suite.Config().IsExpectedClusterCount(expectedNumberOfClusters) { os.Exit(suite.Run()) } else { - fmt.Println("Skipping partitions tests because -enable-multi-cluster is not set") + fmt.Println(fmt.Sprintf("Skipping partitions tests because either -enable-multi-cluster is "+ + "not set or the number of clusters did not match the expected count of %d", expectedNumberOfClusters)) os.Exit(0) } } diff --git a/acceptance/tests/partitions/partitions_connect_test.go b/acceptance/tests/partitions/partitions_connect_test.go index b14f079a68..aa73c17047 100644 --- a/acceptance/tests/partitions/partitions_connect_test.go +++ b/acceptance/tests/partitions/partitions_connect_test.go @@ -11,7 +11,6 @@ import ( terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -85,7 +84,7 @@ func TestPartitions_Connect(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { defaultPartitionClusterContext := env.DefaultContext(t) - secondaryPartitionClusterContext := env.Context(t, environment.SecondaryContextName) + secondaryPartitionClusterContext := env.Context(t, 1) commonHelmValues := map[string]string{ "global.adminPartitions.enabled": "true", diff --git a/acceptance/tests/partitions/partitions_gateway_test.go b/acceptance/tests/partitions/partitions_gateway_test.go index 06bc933ce8..5c85e6725b 100644 --- a/acceptance/tests/partitions/partitions_gateway_test.go +++ b/acceptance/tests/partitions/partitions_gateway_test.go @@ -12,7 +12,6 @@ import ( terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -37,7 +36,7 @@ func TestPartitions_Gateway(t *testing.T) { const secondaryPartition = "secondary" defaultPartitionClusterContext := env.DefaultContext(t) - secondaryPartitionClusterContext := env.Context(t, environment.SecondaryContextName) + secondaryPartitionClusterContext := env.Context(t, 1) commonHelmValues := map[string]string{ "global.adminPartitions.enabled": "true", diff --git a/acceptance/tests/partitions/partitions_sync_test.go b/acceptance/tests/partitions/partitions_sync_test.go index cf32c97ae3..8eaaff099e 100644 --- a/acceptance/tests/partitions/partitions_sync_test.go +++ b/acceptance/tests/partitions/partitions_sync_test.go @@ -11,7 +11,6 @@ import ( terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -82,7 +81,7 @@ func TestPartitions_Sync(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { primaryClusterContext := env.DefaultContext(t) - secondaryClusterContext := env.Context(t, environment.SecondaryContextName) + secondaryClusterContext := env.Context(t, 1) commonHelmValues := map[string]string{ "global.adminPartitions.enabled": "true", diff --git a/acceptance/tests/peering/main_test.go b/acceptance/tests/peering/main_test.go index 64c5f8ed03..075051861d 100644 --- a/acceptance/tests/peering/main_test.go +++ b/acceptance/tests/peering/main_test.go @@ -16,10 +16,12 @@ var suite testsuite.Suite func TestMain(m *testing.M) { suite = testsuite.NewSuite(m) - if suite.Config().EnableMultiCluster && !suite.Config().DisablePeering { + expectedNumberOfClusters := 2 + if suite.Config().EnableMultiCluster && suite.Config().IsExpectedClusterCount(expectedNumberOfClusters) && !suite.Config().DisablePeering { os.Exit(suite.Run()) } else { - fmt.Println("Skipping peering tests because either -enable-multi-cluster is not set or -disable-peering is set") + fmt.Println(fmt.Sprintf("Skipping peerings tests because either -enable-multi-cluster is "+ + "not set, -disable-peering is set, or the number of clusters did not match the expected count of %d", expectedNumberOfClusters)) os.Exit(0) } } diff --git a/acceptance/tests/peering/peering_connect_namespaces_test.go b/acceptance/tests/peering/peering_connect_namespaces_test.go index 9276582db3..622e547091 100644 --- a/acceptance/tests/peering/peering_connect_namespaces_test.go +++ b/acceptance/tests/peering/peering_connect_namespaces_test.go @@ -12,7 +12,6 @@ import ( terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -93,7 +92,7 @@ func TestPeering_ConnectNamespaces(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { staticServerPeerClusterContext := env.DefaultContext(t) - staticClientPeerClusterContext := env.Context(t, environment.SecondaryContextName) + staticClientPeerClusterContext := env.Context(t, 1) commonHelmValues := map[string]string{ "global.peering.enabled": "true", diff --git a/acceptance/tests/peering/peering_connect_test.go b/acceptance/tests/peering/peering_connect_test.go index ad62ca6926..a14cf3a805 100644 --- a/acceptance/tests/peering/peering_connect_test.go +++ b/acceptance/tests/peering/peering_connect_test.go @@ -12,7 +12,6 @@ import ( terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -53,7 +52,7 @@ func TestPeering_Connect(t *testing.T) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { staticServerPeerClusterContext := env.DefaultContext(t) - staticClientPeerClusterContext := env.Context(t, environment.SecondaryContextName) + staticClientPeerClusterContext := env.Context(t, 1) commonHelmValues := map[string]string{ "global.peering.enabled": "true", diff --git a/acceptance/tests/peering/peering_gateway_test.go b/acceptance/tests/peering/peering_gateway_test.go index 76698102e6..17824b8e69 100644 --- a/acceptance/tests/peering/peering_gateway_test.go +++ b/acceptance/tests/peering/peering_gateway_test.go @@ -11,7 +11,6 @@ import ( terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -42,7 +41,7 @@ func TestPeering_Gateway(t *testing.T) { const staticClientPeer = "client" staticServerPeerClusterContext := env.DefaultContext(t) - staticClientPeerClusterContext := env.Context(t, environment.SecondaryContextName) + staticClientPeerClusterContext := env.Context(t, 1) commonHelmValues := map[string]string{ "global.peering.enabled": "true", diff --git a/acceptance/tests/vault/main_test.go b/acceptance/tests/vault/main_test.go index e20892bf1c..02a22c2b79 100644 --- a/acceptance/tests/vault/main_test.go +++ b/acceptance/tests/vault/main_test.go @@ -4,6 +4,7 @@ package vault import ( + "fmt" "os" "testing" @@ -14,5 +15,13 @@ var suite testsuite.Suite func TestMain(m *testing.M) { suite = testsuite.NewSuite(m) - os.Exit(suite.Run()) + + expectedNumberOfClusters := 2 + if suite.Config().EnableMultiCluster && suite.Config().IsExpectedClusterCount(expectedNumberOfClusters) { + os.Exit(suite.Run()) + } else { + fmt.Println(fmt.Sprintf("Skipping vault tests because either -enable-multi-cluster is "+ + "not set or the number of clusters did not match the expected count of %d", expectedNumberOfClusters)) + os.Exit(0) + } } diff --git a/acceptance/tests/vault/vault_partitions_test.go b/acceptance/tests/vault/vault_partitions_test.go index 53bdc23e97..63002993a6 100644 --- a/acceptance/tests/vault/vault_partitions_test.go +++ b/acceptance/tests/vault/vault_partitions_test.go @@ -9,7 +9,6 @@ import ( "testing" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -26,7 +25,7 @@ func TestVault_Partitions(t *testing.T) { env := suite.Environment() cfg := suite.Config() serverClusterCtx := env.DefaultContext(t) - clientClusterCtx := env.Context(t, environment.SecondaryContextName) + clientClusterCtx := env.Context(t, 1) ns := serverClusterCtx.KubectlOptions(t).Namespace const secondaryPartition = "secondary" diff --git a/acceptance/tests/vault/vault_wan_fed_test.go b/acceptance/tests/vault/vault_wan_fed_test.go index 21a86937f4..d8c00b732a 100644 --- a/acceptance/tests/vault/vault_wan_fed_test.go +++ b/acceptance/tests/vault/vault_wan_fed_test.go @@ -44,7 +44,7 @@ func TestVault_WANFederationViaGateways(t *testing.T) { } primaryCtx := suite.Environment().DefaultContext(t) - secondaryCtx := suite.Environment().Context(t, environment.SecondaryContextName) + secondaryCtx := suite.Environment().Context(t, 1) ns := primaryCtx.KubectlOptions(t).Namespace diff --git a/acceptance/tests/wan-federation/main_test.go b/acceptance/tests/wan-federation/main_test.go index ced18d5cc7..4a47a8a00f 100644 --- a/acceptance/tests/wan-federation/main_test.go +++ b/acceptance/tests/wan-federation/main_test.go @@ -16,10 +16,12 @@ var suite testsuite.Suite func TestMain(m *testing.M) { suite = testsuite.NewSuite(m) - if suite.Config().EnableMultiCluster { + expectedNumberOfClusters := 2 + if suite.Config().EnableMultiCluster && suite.Config().IsExpectedClusterCount(expectedNumberOfClusters) { os.Exit(suite.Run()) } else { - fmt.Println("Skipping wan federation tests because -enable-multi-cluster is not set") + fmt.Println(fmt.Sprintf("Skipping wan-federation tests because either -enable-multi-cluster is "+ + "not set or the number of clusters did not match the expected count of %d", expectedNumberOfClusters)) os.Exit(0) } } diff --git a/acceptance/tests/wan-federation/wan_federation_gateway_test.go b/acceptance/tests/wan-federation/wan_federation_gateway_test.go index 0ef48b9920..c87ee7197b 100644 --- a/acceptance/tests/wan-federation/wan_federation_gateway_test.go +++ b/acceptance/tests/wan-federation/wan_federation_gateway_test.go @@ -33,7 +33,7 @@ func TestWANFederation_Gateway(t *testing.T) { } primaryContext := env.DefaultContext(t) - secondaryContext := env.Context(t, environment.SecondaryContextName) + secondaryContext := env.Context(t, 1) primaryHelmValues := map[string]string{ "global.datacenter": "dc1", diff --git a/acceptance/tests/wan-federation/wan_federation_test.go b/acceptance/tests/wan-federation/wan_federation_test.go index ced126af42..e7a128887e 100644 --- a/acceptance/tests/wan-federation/wan_federation_test.go +++ b/acceptance/tests/wan-federation/wan_federation_test.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" @@ -49,7 +48,7 @@ func TestWANFederation(t *testing.T) { } primaryContext := env.DefaultContext(t) - secondaryContext := env.Context(t, environment.SecondaryContextName) + secondaryContext := env.Context(t, 1) primaryHelmValues := map[string]string{ "global.datacenter": "dc1", From 59228dd4cb064e892a6ef80668c447eb3689ca54 Mon Sep 17 00:00:00 2001 From: "hashicorp-copywrite[bot]" <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Date: Mon, 17 Jul 2023 15:04:09 -0400 Subject: [PATCH 072/120] [COMPLIANCE] Add Copyright and License Headers (#2577) Add copyright and license headers --- control-plane/api-gateway/binding/result_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/control-plane/api-gateway/binding/result_test.go b/control-plane/api-gateway/binding/result_test.go index c6987cdaeb..6989bb09ab 100644 --- a/control-plane/api-gateway/binding/result_test.go +++ b/control-plane/api-gateway/binding/result_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package binding import ( From ab462d0a483c6b31c6d6846f61fc6b66c45c0540 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Tue, 18 Jul 2023 11:01:55 -0500 Subject: [PATCH 073/120] Consume gateway-api v0.7.1 for acceptance testing (#2578) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes proposed in this PR: - Consume the same version of gateway-api for acceptance testing that we're consuming in the control plane: https://github.com/hashicorp/consul-k8s/blob/29b6ed36923498afc8f377455d4275653960230f/control-plane/go.mod#L42 How I've tested this PR: - 👀 - 🤖 tests pass How I expect reviewers to test this PR: - See above Checklist: - [ ] Tests added - [ ] [CHANGELOG entry added](https://github.com/hashicorp/consul-k8s/blob/main/CONTRIBUTING.md#adding-a-changelog-entry) --- acceptance/go.mod | 2 +- acceptance/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/acceptance/go.mod b/acceptance/go.mod index 02ef978cf6..382d9f8225 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -19,7 +19,7 @@ require ( k8s.io/client-go v0.26.3 k8s.io/utils v0.0.0-20230209194617-a36077c30491 sigs.k8s.io/controller-runtime v0.14.6 - sigs.k8s.io/gateway-api v0.7.0 + sigs.k8s.io/gateway-api v0.7.1 ) require ( diff --git a/acceptance/go.sum b/acceptance/go.sum index b3aaefe655..53b9400c42 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -1264,8 +1264,8 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= -sigs.k8s.io/gateway-api v0.7.0 h1:/mG8yyJNBifqvuVLW5gwlI4CQs0NR/5q4BKUlf1bVdY= -sigs.k8s.io/gateway-api v0.7.0/go.mod h1:Xv0+ZMxX0lu1nSSDIIPEfbVztgNZ+3cfiYrJsa2Ooso= +sigs.k8s.io/gateway-api v0.7.1 h1:Tts2jeepVkPA5rVG/iO+S43s9n7Vp7jCDhZDQYtPigQ= +sigs.k8s.io/gateway-api v0.7.1/go.mod h1:Xv0+ZMxX0lu1nSSDIIPEfbVztgNZ+3cfiYrJsa2Ooso= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= From c790951382235e9a5f10365d1b46fba16c5f2e5a Mon Sep 17 00:00:00 2001 From: chappie <6537530+chapmanc@users.noreply.github.com> Date: Tue, 18 Jul 2023 12:10:23 -0600 Subject: [PATCH 074/120] Update to handle validation endpoints (#2580) Changes proposed in this PR: - add in new validation call in endpoint How I've tested this PR: Ran it locally and tested the changes How I expect reviewers to test this PR: Read the code and run the command themselves to verify: ``` ./consul-k8s/acceptance/tests/cloud && go test -run TestBasicCloud -v -p 1 -timeout 20m \ -use-kind \ -kubecontext="kind-dc1" \ -consul-image hashicorppreview/consul-enterprise:1.17-dev -consul-k8s-image hashicorppreview/consul-k8s-control-plane:1.3.0-dev -consul-collector-image hashicorp/consul-telemetry-collector:0.0.1 \ -enable-enterprise ``` Checklist: - [X] Tests added - [n/a] [CHANGELOG entry added](https://github.com/hashicorp/consul-k8s/blob/main/CONTRIBUTING.md#adding-a-changelog-entry) --- acceptance/tests/cloud/basic_test.go | 59 ++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/acceptance/tests/cloud/basic_test.go b/acceptance/tests/cloud/basic_test.go index 7a0a31430a..0b5e3da719 100644 --- a/acceptance/tests/cloud/basic_test.go +++ b/acceptance/tests/cloud/basic_test.go @@ -129,7 +129,7 @@ func TestBasicCloud(t *testing.T) { localPort, 443, logger.TestLogger{}) - + defer tunnel.Close() // Retry creating the port forward since it can fail occasionally. retry.RunWith(&retry.Counter{Wait: 5 * time.Second, Count: 60}, t, func(r *retry.R) { // NOTE: It's okay to pass in `t` to ForwardPortE despite being in a retry @@ -144,7 +144,7 @@ func TestBasicCloud(t *testing.T) { logger.Log(t, "error finding consul token") return } - tunnel.Close() + logger.Log(t, "consul test token :"+consulToken) releaseName := helpers.RandomName() @@ -229,6 +229,57 @@ func TestBasicCloud(t *testing.T) { logger.Log(t, "creating static-server deployment") k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") - // time.Sleep(1 * time.Hour) - // TODO: add in test assertions here + t.Log("Finished deployment. Validating expected conditions now") + // Give some time for collector send metrics + time.Sleep(5 * time.Second) + err = validate(tunnel.Endpoint()) + logger.Log(t, fmt.Sprintf("result: %v", err)) + require.NoError(t, err) + +} + +func validate(endpoint string) error { + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + + client := &http.Client{Transport: tr} + url := fmt.Sprintf("https://%s/validation", endpoint) + req, err := http.NewRequest("GET", url, nil) + if err != nil { + fmt.Println("Error creating request:", err) + return errors.New("error creating validation request") + } + + // Perform the request + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error sending request:", err) + return errors.New("error making validation request") + } + if resp.StatusCode == http.StatusExpectationFailed { + // Read the response body + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println("Error reading response:", err) + return errors.New("error reading body") + } + var message errMsg + err = json.Unmarshal(body, &message) + if err != nil { + fmt.Println("Error parsing response:", err) + return errors.New("error parsing body") + } + + return fmt.Errorf("Failed validation: %s", message) + } else if resp.StatusCode != http.StatusOK { + return errors.New("unexpected status code response from failure") + } + + return nil + +} + +type errMsg struct { + Error string `json:"error"` } From 07cc5cd57733f90c0ac7a1defe35ebef57dec437 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Wed, 19 Jul 2023 09:50:08 -0400 Subject: [PATCH 075/120] test(eks): fix deprecated CSI driver terraform (#2584) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes proposed in this PR: - Replacing the deprecated [`resolve_conflicts`](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/eks_addon#resolve_conflicts) with the new attributes. I don't know if we really need this setting since it is optional and the addon has no user-defined config, but I'm keeping this to keep the behavior consistent. How I've tested this PR: I did not. How I expect reviewers to test this PR: 👀 Checklist: - [ ] ~Tests added~ - [ ] ~[CHANGELOG entry added](https://github.com/hashicorp/consul-k8s/blob/main/CONTRIBUTING.md#adding-a-changelog-entry)~ --- charts/consul/test/terraform/eks/main.tf | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/charts/consul/test/terraform/eks/main.tf b/charts/consul/test/terraform/eks/main.tf index efbab0e833..3bc8b40451 100644 --- a/charts/consul/test/terraform/eks/main.tf +++ b/charts/consul/test/terraform/eks/main.tf @@ -124,12 +124,13 @@ resource "aws_iam_role_policy_attachment" "csi" { } resource "aws_eks_addon" "csi-driver" { - count = var.cluster_count - cluster_name = module.eks[count.index].cluster_id - addon_name = "aws-ebs-csi-driver" - addon_version = "v1.15.0-eksbuild.1" - service_account_role_arn = aws_iam_role.csi-driver-role[count.index].arn - resolve_conflicts = "OVERWRITE" + count = var.cluster_count + cluster_name = module.eks[count.index].cluster_id + addon_name = "aws-ebs-csi-driver" + addon_version = "v1.15.0-eksbuild.1" + service_account_role_arn = aws_iam_role.csi-driver-role[count.index].arn + resolve_conflicts_on_create = "OVERWRITE" + resolve_conflicts_on_update = "OVERWRITE" } data "aws_eks_cluster" "cluster" { From f0530d9a5ac9c0e8ee5de910975bd722a4ade2c0 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Wed, 19 Jul 2023 13:53:00 -0400 Subject: [PATCH 076/120] Add a check to prevent a nil-pointer dereference on Ingress LB (#2592) --- control-plane/catalog/to-consul/resource.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/control-plane/catalog/to-consul/resource.go b/control-plane/catalog/to-consul/resource.go index 08aeec8821..2d29d6c15a 100644 --- a/control-plane/catalog/to-consul/resource.go +++ b/control-plane/catalog/to-consul/resource.go @@ -938,7 +938,7 @@ func (t *serviceIngressResource) Upsert(key string, raw interface{}) error { continue } if t.SyncLoadBalancerIPs { - if ingress.Status.LoadBalancer.Ingress[0].IP == "" { + if len(ingress.Status.LoadBalancer.Ingress) > 0 && ingress.Status.LoadBalancer.Ingress[0].IP == "" { continue } hostName = ingress.Status.LoadBalancer.Ingress[0].IP From b3769b1cb19004112f83badd5028a3fce1030bb4 Mon Sep 17 00:00:00 2001 From: Dan Stough Date: Wed, 19 Jul 2023 14:13:27 -0400 Subject: [PATCH 077/120] test: remove unused workflow inputs (#2589) Changes proposed in this PR: - Removed unused workflow inputs. --- .github/workflows/merge.yml | 3 +-- .github/workflows/nightly-acceptance.yml | 3 +-- .github/workflows/nightly-api-gateway-conformance.yml | 1 - .github/workflows/nightly-cleanup.yml | 3 +-- .github/workflows/weekly-acceptance-0-49-x.yml | 3 +-- .github/workflows/weekly-acceptance-1-0-x.yml | 3 +-- .github/workflows/weekly-acceptance-1-1-x.yml | 3 +-- 7 files changed, 6 insertions(+), 13 deletions(-) diff --git a/.github/workflows/merge.yml b/.github/workflows/merge.yml index 201df1dadd..e95af6cdcc 100644 --- a/.github/workflows/merge.yml +++ b/.github/workflows/merge.yml @@ -11,7 +11,6 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.17-dev # Consul's enterprise version to use in tests. We use this consul image on release branches too BRANCH: ${{ github.head_ref || github.ref_name }} CONTEXT: "merge" SHA: ${{ github.event.pull_request.head.sha || github.sha }} @@ -28,4 +27,4 @@ jobs: repo: hashicorp/consul-k8s-workflows ref: main token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ env.SHA }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}", "consul-image":"${{ env.CONSUL_IMAGE }}" }' + inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ env.SHA }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' diff --git a/.github/workflows/nightly-acceptance.yml b/.github/workflows/nightly-acceptance.yml index 4d437b4990..6db7684bb8 100644 --- a/.github/workflows/nightly-acceptance.yml +++ b/.github/workflows/nightly-acceptance.yml @@ -8,7 +8,6 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.17-dev # Consul's enterprise version to use in tests BRANCH: ${{ github.ref_name }} CONTEXT: "nightly" @@ -24,4 +23,4 @@ jobs: repo: hashicorp/consul-k8s-workflows ref: main token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}", "consul-image":"${{ env.CONSUL_IMAGE }}" }' + inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' diff --git a/.github/workflows/nightly-api-gateway-conformance.yml b/.github/workflows/nightly-api-gateway-conformance.yml index 5038ffdb93..abeec34659 100644 --- a/.github/workflows/nightly-api-gateway-conformance.yml +++ b/.github/workflows/nightly-api-gateway-conformance.yml @@ -9,7 +9,6 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.17-dev # Consul's enterprise version to use in tests BRANCH: ${{ github.ref_name }} CONTEXT: "nightly" diff --git a/.github/workflows/nightly-cleanup.yml b/.github/workflows/nightly-cleanup.yml index 4a304549df..83d6688ac5 100644 --- a/.github/workflows/nightly-cleanup.yml +++ b/.github/workflows/nightly-cleanup.yml @@ -8,7 +8,6 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: "not used" BRANCH: ${{ github.ref_name }} CONTEXT: "nightly" @@ -24,4 +23,4 @@ jobs: repo: hashicorp/consul-k8s-workflows ref: main token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}", "consul-image":"${{ env.CONSUL_IMAGE }}" }' + inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' diff --git a/.github/workflows/weekly-acceptance-0-49-x.yml b/.github/workflows/weekly-acceptance-0-49-x.yml index adba13846a..5e1c17f3c7 100644 --- a/.github/workflows/weekly-acceptance-0-49-x.yml +++ b/.github/workflows/weekly-acceptance-0-49-x.yml @@ -10,7 +10,6 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.13-dev # Consul's enterprise version to use in tests BRANCH: "release/0.49.x" CONTEXT: "weekly" @@ -26,4 +25,4 @@ jobs: repo: hashicorp/consul-k8s-workflows ref: main token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}", "consul-image":"${{ env.CONSUL_IMAGE }}" }' + inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' diff --git a/.github/workflows/weekly-acceptance-1-0-x.yml b/.github/workflows/weekly-acceptance-1-0-x.yml index 72769f0ca1..11dda52bed 100644 --- a/.github/workflows/weekly-acceptance-1-0-x.yml +++ b/.github/workflows/weekly-acceptance-1-0-x.yml @@ -11,7 +11,6 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.14-dev # Consul's enterprise version to use in tests BRANCH: "release/1.0.x" CONTEXT: "weekly" @@ -27,4 +26,4 @@ jobs: repo: hashicorp/consul-k8s-workflows ref: main token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}", "consul-image":"${{ env.CONSUL_IMAGE }}" }' + inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' diff --git a/.github/workflows/weekly-acceptance-1-1-x.yml b/.github/workflows/weekly-acceptance-1-1-x.yml index b77da7eff0..86153587b0 100644 --- a/.github/workflows/weekly-acceptance-1-1-x.yml +++ b/.github/workflows/weekly-acceptance-1-1-x.yml @@ -11,7 +11,6 @@ on: # these should be the only settings that you will ever need to change env: - CONSUL_IMAGE: hashicorppreview/consul-enterprise:1.15-dev # Consul's enterprise version to use in tests BRANCH: "release/1.1.x" CONTEXT: "weekly" @@ -27,4 +26,4 @@ jobs: repo: hashicorp/consul-k8s-workflows ref: main token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}", "consul-image":"${{ env.CONSUL_IMAGE }}" }' + inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' From 4d4c35a832fdebc87364c7ca895533ca2838b963 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Wed, 19 Jul 2023 22:57:49 -0400 Subject: [PATCH 078/120] chore: Update actions for security (#2601) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes proposed in this PR: - Update actions that are out of date How I've tested this PR: 👀 How I expect reviewers to test this PR: 👀 Checklist: - [ ] Tests added - [ ] [CHANGELOG entry added](https://github.com/hashicorp/consul-k8s/blob/main/CONTRIBUTING.md#adding-a-changelog-entry) --- .github/workflows/build.yml | 18 +++++++++--------- .github/workflows/changelog-checker.yml | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 917456e9d0..1d7942617d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: outputs: go-version: ${{ steps.get-go-version.outputs.go-version }} steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Determine Go version id: get-go-version # We use .go-version as our source of truth for current Go @@ -35,7 +35,7 @@ jobs: outputs: product-version: ${{ steps.get-product-version.outputs.product-version }} steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: get product version id: get-product-version run: | @@ -49,7 +49,7 @@ jobs: filepath: ${{ steps.generate-metadata-file.outputs.filepath }} steps: - name: "Checkout directory" - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Generate metadata file id: generate-metadata-file uses: hashicorp/actions-generate-metadata@v1 @@ -121,7 +121,7 @@ jobs: name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} ${{ matrix.component }} ${{ matrix.fips }} build steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Setup go uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 @@ -193,7 +193,7 @@ jobs: - name: Test rpm package if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} - uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" + uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" with: image: registry.access.redhat.com/ubi9/ubi:latest options: -v ${{ github.workspace }}:/work @@ -218,7 +218,7 @@ jobs: - name: Test debian package if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} - uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" + uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" with: image: ubuntu:latest options: -v ${{ github.workspace }}:/work @@ -258,7 +258,7 @@ jobs: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_${{ matrix.goos}}_${{ matrix.goarch }}.zip @@ -328,7 +328,7 @@ jobs: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_linux_${{ matrix.arch }}.zip @@ -391,7 +391,7 @@ jobs: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_linux_${{ matrix.arch }}.zip diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml index 1eea4196e7..40c9b17c68 100644 --- a/.github/workflows/changelog-checker.yml +++ b/.github/workflows/changelog-checker.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 # by default the checkout action doesn't checkout all branches From a4d9487df5613afc518f2275ca541c3d297c7dca Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Thu, 20 Jul 2023 15:28:59 -0400 Subject: [PATCH 079/120] [NET-4122] Doc guidance for federation with externalServers (#2583) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add guidance for proper configuration when joining to a secondary cluster using WAN fed with external servers also enabled. Also clarify federation requirements and fix formatting for an unrelated value. Changes proposed in this PR: - Update base content for generating Helm chart docs to clarify the use case encountered in https://github.com/hashicorp/consul-k8s/issues/2138 - Minor additional fixes - _Follow-up: propagate generated doc changes to `consul` and additionally update https://developer.hashicorp.com/consul/docs/k8s/deployment-configurations/servers-outside-kubernetes there_ How I've tested this PR: N/A (docs only) How I expect reviewers to test this PR: 👀 Checklist: - [ ] Tests added - [ ] [CHANGELOG entry added](https://github.com/hashicorp/consul-k8s/blob/main/CONTRIBUTING.md#adding-a-changelog-entry) --- charts/consul/values.yaml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 12c45ac958..81065d4bb2 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -535,8 +535,9 @@ global: # If enabled, this datacenter will be federation-capable. Only federation # via mesh gateways is supported. # Mesh gateways and servers will be configured to allow federation. - # Requires `global.tls.enabled`, `meshGateway.enabled` and `connectInject.enabled` - # to be true. Requires Consul 1.8+. + # Requires `global.tls.enabled`, `connectInject.enabled`, and one of + # `meshGateway.enabled` or `externalServers.enabled` to be true. + # Requires Consul 1.8+. enabled: false # If true, the chart will create a Kubernetes secret that can be imported @@ -552,8 +553,8 @@ global: # @type: string primaryDatacenter: null - # A list of addresses of the primary mesh gateways in the form `:`. - # (e.g. ["1.1.1.1:443", "2.3.4.5:443"] + # A list of addresses of the primary mesh gateways in the form `:` + # (e.g. `["1.1.1.1:443", "2.3.4.5:443"]`). # @type: array primaryGateways: [] @@ -564,6 +565,9 @@ global: # from the one used by the Consul Service Mesh. # Please refer to the [Kubernetes Auth Method documentation](https://developer.hashicorp.com/consul/docs/security/acl/auth-methods/kubernetes). # + # If `externalServers.enabled` is set to true, `global.federation.k8sAuthMethodHost` and + # `externalServers.k8sAuthMethodHost` should be set to the same value. + # # You can retrieve this value from your `kubeconfig` by running: # # ```shell-session @@ -1339,6 +1343,9 @@ externalServers: # This address must be reachable from the Consul servers. # Please refer to the [Kubernetes Auth Method documentation](https://developer.hashicorp.com/consul/docs/security/acl/auth-methods/kubernetes). # + # If `global.federation.enabled` is set to true, `global.federation.k8sAuthMethodHost` and + # `externalServers.k8sAuthMethodHost` should be set to the same value. + # # You could retrieve this value from your `kubeconfig` by running: # # ```shell-session From 414554c056d5b66131bc0f6a58d6c7ef1b3d29ce Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Thu, 20 Jul 2023 16:53:47 -0400 Subject: [PATCH 080/120] Handle errors properly when services are de-registered from the catalog (#2571) - In the past, kubernetes nodes were used as the source of truth to determine the list of services that should exist in Consul. - In most cases this was ok but becomes a problem when nodes are quickly deleted from kubernetes such as the case when using spot instances. - Instead, use consul synthetic-nodes to get the list of services and deregister the services that do not have endpoint addresses. --------- Co-authored-by: mr-miles --- .changelog/2571.txt | 3 + .../endpoints/endpoints_controller.go | 62 ++++++---- .../endpoints/endpoints_controller_test.go | 117 ++++++++++++++++++ 3 files changed, 159 insertions(+), 23 deletions(-) create mode 100644 .changelog/2571.txt diff --git a/.changelog/2571.txt b/.changelog/2571.txt new file mode 100644 index 0000000000..91b3f2943b --- /dev/null +++ b/.changelog/2571.txt @@ -0,0 +1,3 @@ +```release-note:bug +control-plane: fix bug in endpoints controller when deregistering services from consul when a node is deleted. +``` diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go index 7b236792ab..cdf56b187f 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go @@ -159,7 +159,6 @@ func (r *Controller) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu } err = r.Client.Get(ctx, req.NamespacedName, &serviceEndpoints) - // endpointPods holds a set of all pods this endpoints object is currently pointing to. // We use this later when we reconcile ACL tokens to decide whether an ACL token in Consul // is for a pod that no longer exists. @@ -183,7 +182,7 @@ func (r *Controller) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu // It is possible that the endpoints object has never been registered, in which case deregistration is a no-op. if isLabeledIgnore(serviceEndpoints.Labels) { // We always deregister the service to handle the case where a user has registered the service, then added the label later. - r.Log.Info("Ignoring endpoint labeled with `consul.hashicorp.com/service-ignore: \"true\"`", "name", req.Name, "namespace", req.Namespace) + r.Log.Info("ignoring endpoint labeled with `consul.hashicorp.com/service-ignore: \"true\"`", "name", req.Name, "namespace", req.Namespace) err = r.deregisterService(apiClient, req.Name, req.Namespace, nil) return ctrl.Result{}, err } @@ -915,14 +914,14 @@ func getHealthCheckStatusReason(healthCheckStatus, podName, podNamespace string) // them only if they are not in endpointsAddressesMap. If the map is nil, it will deregister all instances. If the map // has addresses, it will only deregister instances not in the map. func (r *Controller) deregisterService(apiClient *api.Client, k8sSvcName, k8sSvcNamespace string, endpointsAddressesMap map[string]bool) error { - // Get services matching metadata. - nodesWithSvcs, err := r.serviceInstancesForK8sNodes(apiClient, k8sSvcName, k8sSvcNamespace) + // Get services matching metadata from Consul + nodesWithSvcs, err := r.serviceInstancesForNodes(apiClient, k8sSvcName, k8sSvcNamespace) if err != nil { r.Log.Error(err, "failed to get service instances", "name", k8sSvcName) return err } - // Deregister each service instance that matches the metadata. + var errs error for _, nodeSvcs := range nodesWithSvcs { for _, svc := range nodeSvcs.Services { // We need to get services matching "k8s-service-name" and "k8s-namespace" metadata. @@ -933,42 +932,48 @@ func (r *Controller) deregisterService(apiClient *api.Client, k8sSvcName, k8sSvc if _, ok := endpointsAddressesMap[svc.Address]; !ok { // If the service address is not in the Endpoints addresses, deregister it. r.Log.Info("deregistering service from consul", "svc", svc.ID) - _, err = apiClient.Catalog().Deregister(&api.CatalogDeregistration{ + _, err := apiClient.Catalog().Deregister(&api.CatalogDeregistration{ Node: nodeSvcs.Node.Node, ServiceID: svc.ID, Namespace: svc.Namespace, }, nil) if err != nil { + // Do not exit right away as there might be other services that need to be deregistered. r.Log.Error(err, "failed to deregister service instance", "id", svc.ID) - return err + errs = multierror.Append(errs, err) + } else { + serviceDeregistered = true } - serviceDeregistered = true } } else { r.Log.Info("deregistering service from consul", "svc", svc.ID) - if _, err = apiClient.Catalog().Deregister(&api.CatalogDeregistration{ + _, err := apiClient.Catalog().Deregister(&api.CatalogDeregistration{ Node: nodeSvcs.Node.Node, ServiceID: svc.ID, Namespace: svc.Namespace, - }, nil); err != nil { + }, nil) + if err != nil { + // Do not exit right away as there might be other services that need to be deregistered. r.Log.Error(err, "failed to deregister service instance", "id", svc.ID) - return err + errs = multierror.Append(errs, err) + } else { + serviceDeregistered = true } - serviceDeregistered = true } if r.AuthMethod != "" && serviceDeregistered { r.Log.Info("reconciling ACL tokens for service", "svc", svc.Service) - err = r.deleteACLTokensForServiceInstance(apiClient, svc, k8sSvcNamespace, svc.Meta[constants.MetaKeyPodName]) + err := r.deleteACLTokensForServiceInstance(apiClient, svc, k8sSvcNamespace, svc.Meta[constants.MetaKeyPodName]) if err != nil { r.Log.Error(err, "failed to reconcile ACL tokens for service", "svc", svc.Service) - return err + errs = multierror.Append(errs, err) } } } } - return nil + return errs + } // deleteACLTokensForServiceInstance finds the ACL tokens that belongs to the service instance and deletes it from Consul. @@ -1088,21 +1093,32 @@ func getTokenMetaFromDescription(description string) (map[string]string, error) return tokenMeta, nil } -func (r *Controller) serviceInstancesForK8sNodes(apiClient *api.Client, k8sServiceName, k8sServiceNamespace string) ([]*api.CatalogNodeServiceList, error) { +func (r *Controller) serviceInstancesForNodes(apiClient *api.Client, k8sServiceName, k8sServiceNamespace string) ([]*api.CatalogNodeServiceList, error) { var serviceList []*api.CatalogNodeServiceList - // Get a list of k8s nodes. - var nodeList corev1.NodeList - err := r.Client.List(r.Context, &nodeList) + + // The nodelist may have changed between this point and when the event was raised + // For example, if a pod is evicted because a node has been deleted, there is no guarantee that that node will show up here + // query consul catalog for a list of nodes supporting this service + // quite a lot of results as synthetic nodes are never deregistered. + var nodes []*api.Node + filter := fmt.Sprintf(`Meta[%q] == %q `, "synthetic-node", "true") + nodes, _, err := apiClient.Catalog().Nodes(&api.QueryOptions{Filter: filter, Namespace: namespaces.WildcardNamespace}) if err != nil { return nil, err } - for _, node := range nodeList.Items { + + var errs error + for _, node := range nodes { var nodeServices *api.CatalogNodeServiceList - nodeServices, err = r.serviceInstancesForK8SServiceNameAndNamespace(apiClient, k8sServiceName, k8sServiceNamespace, common.ConsulNodeNameFromK8sNode(node.Name)) - serviceList = append(serviceList, nodeServices) + nodeServices, err := r.serviceInstancesForK8SServiceNameAndNamespace(apiClient, k8sServiceName, k8sServiceNamespace, node.Node) + if err != nil { + errs = multierror.Append(errs, err) + } else { + serviceList = append(serviceList, nodeServices) + } } - return serviceList, err + return serviceList, errs } // serviceInstancesForK8SServiceNameAndNamespace calls Consul's ServicesWithFilter to get the list diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go index ea1ce686d6..477be49e9f 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go @@ -893,6 +893,9 @@ func TestReconcileCreateEndpoint_MultiportService(t *testing.T) { catalogRegistration := &api.CatalogRegistration{ Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: svc, } _, err := consulClient.Catalog().Register(catalogRegistration, nil) @@ -2339,6 +2342,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -2358,6 +2364,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -2444,6 +2453,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -2463,6 +2475,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: "127.0.0.1", + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -2549,6 +2564,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -2566,6 +2584,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -2631,6 +2652,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-different-consul-svc-name", Service: "different-consul-svc-name", @@ -2648,6 +2672,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-different-consul-svc-name-sidecar-proxy", @@ -2721,6 +2748,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -2732,6 +2762,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -2835,6 +2868,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -2846,6 +2882,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -2862,6 +2901,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod2-service-updated", Service: "service-updated", @@ -2873,6 +2915,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod2-service-updated-sidecar-proxy", @@ -2932,6 +2977,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-different-consul-svc-name", Service: "different-consul-svc-name", @@ -2943,6 +2991,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-different-consul-svc-name-sidecar-proxy", @@ -2959,6 +3010,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod2-different-consul-svc-name", Service: "different-consul-svc-name", @@ -2970,6 +3024,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod2-different-consul-svc-name-sidecar-proxy", @@ -3015,6 +3072,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -3026,6 +3086,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -3042,6 +3105,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod2-service-updated", Service: "service-updated", @@ -3053,6 +3119,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod2-service-updated-sidecar-proxy", @@ -3088,6 +3157,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-different-consul-svc-name", Service: "different-consul-svc-name", @@ -3099,6 +3171,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-different-consul-svc-name-sidecar-proxy", @@ -3115,6 +3190,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod2-different-consul-svc-name", Service: "different-consul-svc-name", @@ -3126,6 +3204,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod2-different-consul-svc-name-sidecar-proxy", @@ -3174,6 +3255,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -3191,6 +3275,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -3270,6 +3357,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -3287,6 +3377,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -3309,6 +3402,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod2-service-updated", Service: "service-updated", @@ -3326,6 +3422,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod2-service-updated-sidecar-proxy", @@ -3409,6 +3508,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-service-updated", Service: "service-updated", @@ -3426,6 +3528,9 @@ func TestReconcileUpdateEndpoint(t *testing.T) { { Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ Kind: api.ServiceKindConnectProxy, ID: "pod1-service-updated-sidecar-proxy", @@ -4116,6 +4221,9 @@ func TestReconcileDeleteEndpoint(t *testing.T) { serviceRegistration := &api.CatalogRegistration{ Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: svc, } _, err := consulClient.Catalog().Register(serviceRegistration, nil) @@ -4262,6 +4370,9 @@ func TestReconcileIgnoresServiceIgnoreLabel(t *testing.T) { serviceRegistration := &api.CatalogRegistration{ Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-" + svcName, Service: svcName, @@ -4385,6 +4496,9 @@ func TestReconcile_podSpecifiesExplicitService(t *testing.T) { _, err := consulClient.Catalog().Register(&api.CatalogRegistration{ Node: consulNodeName, Address: consulNodeAddress, + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: &api.AgentService{ ID: "pod1-" + svcName, Service: svcName, @@ -4542,6 +4656,9 @@ func TestServiceInstancesForK8SServiceNameAndNamespace(t *testing.T) { catalogRegistration := &api.CatalogRegistration{ Node: consulNodeName, Address: "127.0.0.1", + NodeMeta: map[string]string{ + metaKeySyntheticNode: "true", + }, Service: svc, } _, err = consulClient.Catalog().Register(catalogRegistration, nil) From ff24495eb60406e863a69bc6910d16a671f6873e Mon Sep 17 00:00:00 2001 From: Sujata Roy <61177855+20sr20@users.noreply.github.com> Date: Thu, 20 Jul 2023 16:05:51 -0700 Subject: [PATCH 081/120] Adding support for Enterprise and other improvement on the Customizing Vault Version for WanFed Test (#2481) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adding support for Enterprise and other improvement on the Customizing Vault Version for WanFed Test This is the extension of the PR - https://github.com/hashicorp/consul-k8s/pull/2043 In this PR, the followings were addressed - 1. Now the vault enterprise version can be provided in the cli command. The previous PR only addressed Vault OSS. 2. Two flags “-no-cleanup-wan-fed” and “test-duration” were introduced to not to cleanup the test environment after successful setup to give it time to do manual testing for features/to reproduce customer issues. Default is 1 hour. 3. This was tested in Kind environment and it works fine. The following was taken out to use the “use-kind” option for WanFed test. //if cfg.UseKind { // t.Skipf("Skipping this test because it's currently flaky on kind") //} * Fix indentation * Fix unit test for deleting gateway w/ consul services * Remove redundant service deregistration code * Exit loop early once registration is found for service * Fix import blocking * Set status on pods added to test * Apply suggestions from code review * Reduce count of test gateways to 10 from 100 --------- Co-authored-by: Nathan Coleman Co-authored-by: Sarah Alsmiller Changes proposed in this PR: - - How I've tested this PR: How I expect reviewers to test this PR: Checklist: - [ ] Tests added - [ ] CHANGELOG entry added > HashiCorp engineers only, community PRs should not add a changelog entry. > Entries should use present tense (e.g. Add support for...) * Removing the changes in vault_namespaces_test.go * Introducing new flag no-cleanup * Removed "go 1.20" from go.work file * cfg.USEKind check is added back * Removed previousy added "Test Duration" flag * Some changes * Some changes --- acceptance/framework/config/config.go | 1 + .../framework/connhelper/connect_helper.go | 8 +- acceptance/framework/consul/cli_cluster.go | 4 +- acceptance/framework/consul/helm_cluster.go | 10 +- acceptance/framework/flags/flags.go | 6 + acceptance/framework/helpers/helpers.go | 4 +- acceptance/framework/k8s/deploy.go | 8 +- acceptance/framework/vault/vault_cluster.go | 31 +- .../api_gateway_external_servers_test.go | 6 +- .../api_gateway_gatewayclassconfig_test.go | 31 +- .../api-gateway/api_gateway_lifecycle_test.go | 12 +- .../api-gateway/api_gateway_tenancy_test.go | 6 +- .../tests/api-gateway/api_gateway_test.go | 15 +- acceptance/tests/cloud/basic_test.go | 5 +- acceptance/tests/cloud/remote_dev_test.go | 4 +- .../config_entries_namespaces_test.go | 2 +- .../config-entries/config_entries_test.go | 2 +- .../connect/connect_external_servers_test.go | 6 +- .../connect/connect_inject_namespaces_test.go | 14 +- .../tests/connect/connect_inject_test.go | 8 +- .../tests/connect/permissive_mtls_test.go | 4 +- .../tests/consul-dns/consul_dns_test.go | 2 +- acceptance/tests/example/example_test.go | 2 +- .../ingress_gateway_namespaces_test.go | 12 +- .../ingress-gateway/ingress_gateway_test.go | 4 +- acceptance/tests/metrics/metrics_test.go | 6 +- .../partitions/partitions_connect_test.go | 48 +-- .../partitions/partitions_gateway_test.go | 24 +- .../tests/partitions/partitions_sync_test.go | 8 +- .../peering_connect_namespaces_test.go | 28 +- .../tests/peering/peering_connect_test.go | 24 +- .../tests/peering/peering_gateway_test.go | 28 +- .../sync/sync_catalog_namespaces_test.go | 4 +- acceptance/tests/sync/sync_catalog_test.go | 6 +- .../terminating_gateway_destinations_test.go | 4 +- .../terminating_gateway_namespaces_test.go | 14 +- .../terminating_gateway_test.go | 4 +- .../tests/vault/vault_namespaces_test.go | 8 +- acceptance/tests/vault/vault_test.go | 8 +- .../tests/vault/vault_tls_auto_reload_test.go | 8 +- acceptance/tests/vault/vault_wan_fed_test.go | 10 +- .../wan_federation_gateway_test.go | 18 +- .../wan-federation/wan_federation_test.go | 6 +- go.work | 11 + go.work.sum | 352 ++++++++++++++++++ 45 files changed, 626 insertions(+), 200 deletions(-) create mode 100644 go.work create mode 100644 go.work.sum diff --git a/acceptance/framework/config/config.go b/acceptance/framework/config/config.go index eada42af20..74bb7daf6e 100644 --- a/acceptance/framework/config/config.go +++ b/acceptance/framework/config/config.go @@ -94,6 +94,7 @@ type TestConfig struct { VaultServerVersion string NoCleanupOnFailure bool + NoCleanup bool DebugDirectory string UseAKS bool diff --git a/acceptance/framework/connhelper/connect_helper.go b/acceptance/framework/connhelper/connect_helper.go index 670307da88..c34f663563 100644 --- a/acceptance/framework/connhelper/connect_helper.go +++ b/acceptance/framework/connhelper/connect_helper.go @@ -108,11 +108,11 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if c.Cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-inject") } // Check that both static-server and static-client have been injected and @@ -140,7 +140,7 @@ func (c *ConnectHelper) CreateResolverRedirect(t *testing.T) { kustomizeDir := "../fixtures/cases/resolver-redirect-virtualip" k8s.KubectlApplyK(t, options, kustomizeDir) - helpers.Cleanup(t, c.Cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, options, kustomizeDir) }) } diff --git a/acceptance/framework/consul/cli_cluster.go b/acceptance/framework/consul/cli_cluster.go index 9e119af76d..a45bcc665c 100644 --- a/acceptance/framework/consul/cli_cluster.go +++ b/acceptance/framework/consul/cli_cluster.go @@ -45,6 +45,7 @@ type CLICluster struct { kubeConfig string kubeContext string noCleanupOnFailure bool + noCleanup bool debugDirectory string logger terratestLogger.TestLogger cli cli.CLI @@ -109,6 +110,7 @@ func NewCLICluster( kubeConfig: cfg.GetPrimaryKubeEnv().KubeConfig, kubeContext: cfg.GetPrimaryKubeEnv().KubeContext, noCleanupOnFailure: cfg.NoCleanupOnFailure, + noCleanup: cfg.NoCleanup, debugDirectory: cfg.DebugDirectory, logger: logger, cli: *cli, @@ -122,7 +124,7 @@ func (c *CLICluster) Create(t *testing.T) { // Make sure we delete the cluster if we receive an interrupt signal and // register cleanup so that we delete the cluster when test finishes. - helpers.Cleanup(t, c.noCleanupOnFailure, func() { + helpers.Cleanup(t, c.noCleanupOnFailure, c.noCleanup, func() { c.Destroy(t) }) diff --git a/acceptance/framework/consul/helm_cluster.go b/acceptance/framework/consul/helm_cluster.go index aa6fdef7d8..81787ebfc3 100644 --- a/acceptance/framework/consul/helm_cluster.go +++ b/acceptance/framework/consul/helm_cluster.go @@ -52,6 +52,7 @@ type HelmCluster struct { runtimeClient client.Client kubernetesClient kubernetes.Interface noCleanupOnFailure bool + noCleanup bool debugDirectory string logger terratestLogger.TestLogger } @@ -107,6 +108,7 @@ func NewHelmCluster( runtimeClient: ctx.ControllerRuntimeClient(t), kubernetesClient: ctx.KubernetesClient(t), noCleanupOnFailure: cfg.NoCleanupOnFailure, + noCleanup: cfg.NoCleanup, debugDirectory: cfg.DebugDirectory, logger: logger, } @@ -117,7 +119,7 @@ func (h *HelmCluster) Create(t *testing.T) { // Make sure we delete the cluster if we receive an interrupt signal and // register cleanup so that we delete the cluster when test finishes. - helpers.Cleanup(t, h.noCleanupOnFailure, func() { + helpers.Cleanup(t, h.noCleanupOnFailure, h.noCleanup, func() { h.Destroy(t) }) @@ -508,7 +510,7 @@ func configurePodSecurityPolicies(t *testing.T, client kubernetes.Interface, cfg } } - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { _ = client.PolicyV1beta1().PodSecurityPolicies().Delete(context.Background(), pspName, metav1.DeleteOptions{}) _ = client.RbacV1().ClusterRoles().Delete(context.Background(), pspName, metav1.DeleteOptions{}) _ = client.RbacV1().RoleBindings(namespace).Delete(context.Background(), pspName, metav1.DeleteOptions{}) @@ -559,7 +561,7 @@ func configureSCCs(t *testing.T, client kubernetes.Interface, cfg *config.TestCo } } - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { _ = client.RbacV1().RoleBindings(namespace).Delete(context.Background(), anyuidRoleBinding, metav1.DeleteOptions{}) _ = client.RbacV1().RoleBindings(namespace).Delete(context.Background(), privilegedRoleBinding, metav1.DeleteOptions{}) }) @@ -601,7 +603,7 @@ func CreateK8sSecret(t *testing.T, client kubernetes.Interface, cfg *config.Test } }) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { _ = client.CoreV1().Secrets(namespace).Delete(context.Background(), secretName, metav1.DeleteOptions{}) }) } diff --git a/acceptance/framework/flags/flags.go b/acceptance/framework/flags/flags.go index ad36099b37..b1ad7e4332 100644 --- a/acceptance/framework/flags/flags.go +++ b/acceptance/framework/flags/flags.go @@ -45,6 +45,7 @@ type TestFlags struct { flagHCPResourceID string flagNoCleanupOnFailure bool + flagNoCleanup bool flagDebugDirectory string @@ -124,6 +125,9 @@ func (t *TestFlags) init() { "If true, the tests will not cleanup Kubernetes resources they create when they finish running."+ "Note this flag must be run with -failfast flag, otherwise subsequent tests will fail.") + flag.BoolVar(&t.flagNoCleanup, "no-cleanup", false, + "If true, the tests will not cleanup Kubernetes resources for Vault test") + flag.StringVar(&t.flagDebugDirectory, "debug-directory", "", "The directory where to write debug information about failed test runs, "+ "such as logs and pod definitions. If not provided, a temporary directory will be created by the tests.") @@ -185,6 +189,7 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { kubeEnvs := config.NewKubeTestConfigList(t.flagKubeconfigs, t.flagKubecontexts, t.flagKubeNamespaces) c := &config.TestConfig{ + EnableEnterprise: t.flagEnableEnterprise, EnterpriseLicense: t.flagEnterpriseLicense, @@ -215,6 +220,7 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { HCPResourceID: t.flagHCPResourceID, NoCleanupOnFailure: t.flagNoCleanupOnFailure, + NoCleanup: t.flagNoCleanup, DebugDirectory: tempDir, UseAKS: t.flagUseAKS, UseEKS: t.flagUseEKS, diff --git a/acceptance/framework/helpers/helpers.go b/acceptance/framework/helpers/helpers.go index 3e6ef039b2..f8b1d2f15d 100644 --- a/acceptance/framework/helpers/helpers.go +++ b/acceptance/framework/helpers/helpers.go @@ -87,7 +87,7 @@ func SetupInterruptHandler(cleanup func()) { // Cleanup will both register a cleanup function with t // and SetupInterruptHandler to make sure resources get cleaned up // if an interrupt signal is caught. -func Cleanup(t *testing.T, noCleanupOnFailure bool, cleanup func()) { +func Cleanup(t *testing.T, noCleanupOnFailure bool, noCleanup bool, cleanup func()) { t.Helper() // Always clean up when an interrupt signal is caught. @@ -97,7 +97,7 @@ func Cleanup(t *testing.T, noCleanupOnFailure bool, cleanup func()) { // We need to wrap the cleanup function because t that is passed in to this function // might not have the information on whether the test has failed yet. wrappedCleanupFunc := func() { - if !(noCleanupOnFailure && t.Failed()) { + if !((noCleanupOnFailure && t.Failed()) || noCleanup) { logger.Logf(t, "cleaning up resources for %s", t.Name()) cleanup() } else { diff --git a/acceptance/framework/k8s/deploy.go b/acceptance/framework/k8s/deploy.go index 6834284c33..828586c8cf 100644 --- a/acceptance/framework/k8s/deploy.go +++ b/acceptance/framework/k8s/deploy.go @@ -21,7 +21,7 @@ import ( // Deploy creates a Kubernetes deployment by applying configuration stored at filepath, // sets up a cleanup function and waits for the deployment to become available. -func Deploy(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailure bool, debugDirectory string, filepath string) { +func Deploy(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailure bool, noCleanup bool, debugDirectory string, filepath string) { t.Helper() KubectlApply(t, options, filepath) @@ -33,7 +33,7 @@ func Deploy(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailure bool, err = yaml.NewYAMLOrJSONDecoder(file, 1024).Decode(&deployment) require.NoError(t, err) - helpers.Cleanup(t, noCleanupOnFailure, func() { + helpers.Cleanup(t, noCleanupOnFailure, noCleanup, func() { // Note: this delete command won't wait for pods to be fully terminated. // This shouldn't cause any test pollution because the underlying // objects are deployments, and so when other tests create these @@ -47,7 +47,7 @@ func Deploy(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailure bool, // DeployKustomize creates a Kubernetes deployment by applying the kustomize directory stored at kustomizeDir, // sets up a cleanup function and waits for the deployment to become available. -func DeployKustomize(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailure bool, debugDirectory string, kustomizeDir string) { +func DeployKustomize(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailure bool, noCleanup bool, debugDirectory string, kustomizeDir string) { t.Helper() KubectlApplyK(t, options, kustomizeDir) @@ -59,7 +59,7 @@ func DeployKustomize(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailu err = yaml.NewYAMLOrJSONDecoder(strings.NewReader(output), 1024).Decode(&deployment) require.NoError(t, err) - helpers.Cleanup(t, noCleanupOnFailure, func() { + helpers.Cleanup(t, noCleanupOnFailure, noCleanup, func() { // Note: this delete command won't wait for pods to be fully terminated. // This shouldn't cause any test pollution because the underlying // objects are deployments, and so when other tests create these diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index e0030490c9..4dc832bcb6 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -6,6 +6,8 @@ package vault import ( "context" "fmt" + "os" + "strings" "testing" "time" @@ -13,6 +15,7 @@ import ( terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" terratestLogger "github.com/gruntwork-io/terratest/modules/logger" "github.com/hashicorp/consul-k8s/acceptance/framework/config" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" @@ -44,6 +47,7 @@ type VaultCluster struct { kubernetesClient kubernetes.Interface noCleanupOnFailure bool + noCleanup bool debugDirectory string logger terratestLogger.TestLogger } @@ -54,12 +58,32 @@ func NewVaultCluster(t *testing.T, ctx environment.TestContext, cfg *config.Test logger := terratestLogger.New(logger.TestLogger{}) kopts := ctx.KubectlOptions(t) + ns := ctx.KubectlOptions(t).Namespace + + entstr := "-ent" values := defaultHelmValues(releaseName) if cfg.EnablePodSecurityPolicies { values["global.psp.enable"] = "true" } + vaultReleaseName := helpers.RandomName() + k8sClient := environment.KubernetesClientFromOptions(t, ctx.KubectlOptions(t)) + vaultLicenseSecretName := fmt.Sprintf("%s-enterprise-license", vaultReleaseName) + vaultLicenseSecretKey := "license" + + vaultEnterpriseLicense := os.Getenv("VAULT_LICENSE") + if cfg.VaultServerVersion != "" { + + if strings.Contains(cfg.VaultServerVersion, entstr) { + + logger.Logf(t, "Creating secret for Vault license") + consul.CreateK8sSecret(t, k8sClient, cfg, ns, vaultLicenseSecretName, vaultLicenseSecretKey, vaultEnterpriseLicense) + + values["server.image.repository"] = "docker.mirror.hashicorp.services/hashicorp/vault-enterprise" + values["server.enterpriseLicense.secretName"] = vaultLicenseSecretName + values["server.enterpriseLicense.secretKey"] = vaultLicenseSecretKey + } values["server.image.tag"] = cfg.VaultServerVersion } vaultHelmChartVersion := defaultVaultHelmChartVersion @@ -89,6 +113,7 @@ func NewVaultCluster(t *testing.T, ctx environment.TestContext, cfg *config.Test kubectlOptions: kopts, kubernetesClient: ctx.KubernetesClient(t), noCleanupOnFailure: cfg.NoCleanupOnFailure, + noCleanup: cfg.NoCleanup, debugDirectory: cfg.DebugDirectory, logger: logger, releaseName: releaseName, @@ -224,7 +249,7 @@ func (v *VaultCluster) Create(t *testing.T, ctx environment.TestContext, vaultNa // Make sure we delete the cluster if we receive an interrupt signal and // register cleanup so that we delete the cluster when test finishes. - helpers.Cleanup(t, v.noCleanupOnFailure, func() { + helpers.Cleanup(t, v.noCleanupOnFailure, v.noCleanup, func() { v.Destroy(t) }) @@ -346,7 +371,7 @@ func (v *VaultCluster) createTLSCerts(t *testing.T) { require.NoError(t, err) t.Cleanup(func() { - if !v.noCleanupOnFailure { + if !(v.noCleanupOnFailure || v.noCleanup) { // We're ignoring error here because secret deletion is best-effort. _ = v.kubernetesClient.CoreV1().Secrets(namespace).Delete(context.Background(), certSecretName(v.releaseName), metav1.DeleteOptions{}) _ = v.kubernetesClient.CoreV1().Secrets(namespace).Delete(context.Background(), CASecretName(v.releaseName), metav1.DeleteOptions{}) @@ -419,7 +444,7 @@ func (v *VaultCluster) initAndUnseal(t *testing.T) { rootTokenSecret := fmt.Sprintf("%s-vault-root-token", v.releaseName) v.logger.Logf(t, "saving Vault root token to %q Kubernetes secret", rootTokenSecret) - helpers.Cleanup(t, v.noCleanupOnFailure, func() { + helpers.Cleanup(t, v.noCleanupOnFailure, v.noCleanup, func() { _ = v.kubernetesClient.CoreV1().Secrets(namespace).Delete(context.Background(), rootTokenSecret, metav1.DeleteOptions{}) }) _, err := v.kubernetesClient.CoreV1().Secrets(namespace).Create(context.Background(), &corev1.Secret{ diff --git a/acceptance/tests/api-gateway/api_gateway_external_servers_test.go b/acceptance/tests/api-gateway/api_gateway_external_servers_test.go index c0fa8bbcca..d14ef59990 100644 --- a/acceptance/tests/api-gateway/api_gateway_external_servers_test.go +++ b/acceptance/tests/api-gateway/api_gateway_external_servers_test.go @@ -60,8 +60,8 @@ func TestAPIGateway_ExternalServers(t *testing.T) { consulCluster.Create(t) logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") // Override the default proxy config settings for this test consulClient, _ := consulCluster.SetupConsulClient(t, true, serverReleaseName) @@ -79,7 +79,7 @@ func TestAPIGateway_ExternalServers(t *testing.T) { logger.Log(t, "creating api-gateway resources") out, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-k", "../fixtures/bases/api-gateway") require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-k", "../fixtures/bases/api-gateway") diff --git a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go index 444af6af4d..ffe0424ef1 100644 --- a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go +++ b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go @@ -63,7 +63,23 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { k8sClient := ctx.ControllerRuntimeClient(t) - // Create a GatewayClassConfig. + //create clean namespace + err = k8sClient.Create(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + }) + require.NoError(t, err) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + logger.Log(t, "deleting gateway namesapce") + k8sClient.Delete(context.Background(), &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: namespace, + }, + }) + }) + + // create a GatewayClassConfig with configuration set gatewayClassConfigName := "gateway-class-config" gatewayClassConfig := &v1alpha1.GatewayClassConfig{ ObjectMeta: metav1.ObjectMeta{ @@ -80,7 +96,7 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { logger.Log(t, "creating gateway class config") err = k8sClient.Create(context.Background(), gatewayClassConfig) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all gateway class configs") k8sClient.DeleteAllOf(context.Background(), &v1alpha1.GatewayClassConfig{}) }) @@ -94,7 +110,7 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { // Create gateway class referencing gateway-class-config. logger.Log(t, "creating controlled gateway class") createGatewayClass(t, k8sClient, gatewayClassName, gatewayClassControllerName, gatewayParametersRef) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all gateway classes") k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.GatewayClass{}) }) @@ -119,7 +135,7 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { logger.Log(t, "creating certificate") err = k8sClient.Create(context.Background(), certificate) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8sClient.Delete(context.Background(), certificate) }) @@ -127,7 +143,12 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { gatewayName := "gcctestgateway" + namespace logger.Log(t, "creating controlled gateway") gateway := createGateway(t, k8sClient, gatewayName, namespace, gatewayClassName, certificateName) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + + // make sure it exists + logger.Log(t, "checking that gateway one is synchronized to Consul") + checkConsulExists(t, consulClient, api.APIGateway, gatewayName) + + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all gateways") k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.Gateway{}, client.InNamespace(namespace)) }) diff --git a/acceptance/tests/api-gateway/api_gateway_lifecycle_test.go b/acceptance/tests/api-gateway/api_gateway_lifecycle_test.go index 08712815cc..e3ffa992ce 100644 --- a/acceptance/tests/api-gateway/api_gateway_lifecycle_test.go +++ b/acceptance/tests/api-gateway/api_gateway_lifecycle_test.go @@ -44,7 +44,7 @@ func TestAPIGateway_Lifecycle(t *testing.T) { // create a service to target targetName := "static-server" logger.Log(t, "creating target server") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") // create a basic GatewayClassConfig gatewayClassConfigName := "controlled-gateway-class-config" @@ -56,7 +56,7 @@ func TestAPIGateway_Lifecycle(t *testing.T) { logger.Log(t, "creating gateway class config") err := k8sClient.Create(context.Background(), gatewayClassConfig) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all gateway class configs") k8sClient.DeleteAllOf(context.Background(), &v1alpha1.GatewayClassConfig{}) }) @@ -72,7 +72,7 @@ func TestAPIGateway_Lifecycle(t *testing.T) { logger.Log(t, "creating controlled gateway class one") createGatewayClass(t, k8sClient, controlledGatewayClassOneName, gatewayClassControllerName, gatewayParametersRef) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all gateway classes") k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.GatewayClass{}) }) @@ -105,7 +105,7 @@ func TestAPIGateway_Lifecycle(t *testing.T) { logger.Log(t, "creating certificate") err = k8sClient.Create(context.Background(), certificate) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8sClient.Delete(context.Background(), certificate) }) @@ -114,7 +114,7 @@ func TestAPIGateway_Lifecycle(t *testing.T) { logger.Log(t, "creating controlled gateway one") controlledGatewayOne := createGateway(t, k8sClient, controlledGatewayOneName, defaultNamespace, controlledGatewayClassOneName, certificateName) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all gateways") k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.Gateway{}, client.InNamespace(defaultNamespace)) }) @@ -132,7 +132,7 @@ func TestAPIGateway_Lifecycle(t *testing.T) { logger.Log(t, "creating route one") routeOne := createRoute(t, k8sClient, routeOneName, defaultNamespace, controlledGatewayOneName, targetName) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all http routes") k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.HTTPRoute{}, client.InNamespace(defaultNamespace)) }) diff --git a/acceptance/tests/api-gateway/api_gateway_tenancy_test.go b/acceptance/tests/api-gateway/api_gateway_tenancy_test.go index 716f09bdba..19e85d60b0 100644 --- a/acceptance/tests/api-gateway/api_gateway_tenancy_test.go +++ b/acceptance/tests/api-gateway/api_gateway_tenancy_test.go @@ -100,7 +100,7 @@ func TestAPIGateway_Tenancy(t *testing.T) { routeNamespace, routeK8SOptions := createNamespace(t, ctx, cfg) logger.Logf(t, "creating target server in %s namespace", serviceNamespace) - k8s.DeployKustomize(t, serviceK8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, serviceK8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Logf(t, "creating certificate resources in %s namespace", certificateNamespace) applyFixture(t, cfg, certificateK8SOptions, "cases/api-gateways/certificate") @@ -255,7 +255,7 @@ func applyFixture(t *testing.T, cfg *config.TestConfig, k8sOptions *terratestk8s out, err := k8s.RunKubectlAndGetOutputE(t, k8sOptions, "apply", "-k", path.Join("../fixtures", fixture)) require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectlAndGetOutputE(t, k8sOptions, "delete", "-k", path.Join("../fixtures", fixture)) }) } @@ -267,7 +267,7 @@ func createNamespace(t *testing.T, ctx environment.TestContext, cfg *config.Test logger.Logf(t, "creating Kubernetes namespace %s", namespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", namespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", namespace) }) diff --git a/acceptance/tests/api-gateway/api_gateway_test.go b/acceptance/tests/api-gateway/api_gateway_test.go index 143b793bf8..4b4db38afe 100644 --- a/acceptance/tests/api-gateway/api_gateway_test.go +++ b/acceptance/tests/api-gateway/api_gateway_test.go @@ -7,11 +7,12 @@ import ( "context" "encoding/base64" "fmt" - gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" "strconv" "testing" "time" + gwv1alpha2 "sigs.k8s.io/gateway-api/apis/v1alpha2" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" @@ -75,7 +76,7 @@ func TestAPIGateway_Basic(t *testing.T) { logger.Log(t, "creating api-gateway resources") out, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-k", "../fixtures/bases/api-gateway") require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-k", "../fixtures/bases/api-gateway") @@ -86,7 +87,7 @@ func TestAPIGateway_Basic(t *testing.T) { logger.Log(t, "creating certificate secret") out, err = k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-f", "../fixtures/bases/api-gateway/certificate.yaml") require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-f", "../fixtures/bases/api-gateway/certificate.yaml") @@ -98,17 +99,17 @@ func TestAPIGateway_Basic(t *testing.T) { k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "secret", "certificate", "-p", fmt.Sprintf(`{"data":{"tls.crt":"%s","tls.key":"%s"}}`, base64.StdEncoding.EncodeToString(certificate.CertPEM), base64.StdEncoding.EncodeToString(certificate.PrivateKeyPEM)), "--type=merge") logger.Log(t, "creating target http server") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "patching route to target http server") k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "httproute", "http-route", "-p", `{"spec":{"rules":[{"backendRefs":[{"name":"static-server","port":80}]}]}}`, "--type=merge") logger.Log(t, "creating target tcp server") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server-tcp") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server-tcp") logger.Log(t, "creating tcp-route") k8s.RunKubectl(t, ctx.KubectlOptions(t), "apply", "-f", "../fixtures/cases/api-gateways/tcproute/route.yaml") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-f", "../fixtures/cases/api-gateways/tcproute/route.yaml") @@ -117,7 +118,7 @@ func TestAPIGateway_Basic(t *testing.T) { // We use the static-client pod so that we can make calls to the api gateway // via kubectl exec without needing a route into the cluster from the test machine. logger.Log(t, "creating static-client pod") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-client") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") // Grab a kubernetes client so that we can verify binding // behavior prior to issuing requests through the gateway. diff --git a/acceptance/tests/cloud/basic_test.go b/acceptance/tests/cloud/basic_test.go index 0b5e3da719..e17169700a 100644 --- a/acceptance/tests/cloud/basic_test.go +++ b/acceptance/tests/cloud/basic_test.go @@ -113,7 +113,7 @@ func TestBasicCloud(t *testing.T) { consul.CreateK8sSecret(t, k8sClient, cfg, ns, authUrlSecretName, authUrlSecretKey, authUrlSecretKeyValue) consul.CreateK8sSecret(t, k8sClient, cfg, ns, scadaAddressSecretName, scadaAddressSecretKey, scadaAddressSecretKeyValue) - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/cloud/hcp-mock") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/cloud/hcp-mock") podName, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "get", "pod", "-l", "app=fake-server", "-o", `jsonpath="{.items[0].metadata.name}"`) podName = strings.ReplaceAll(podName, "\"", "") if err != nil { @@ -228,7 +228,8 @@ func TestBasicCloud(t *testing.T) { consulCluster.Create(t) logger.Log(t, "creating static-server deployment") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") t.Log("Finished deployment. Validating expected conditions now") // Give some time for collector send metrics time.Sleep(5 * time.Second) diff --git a/acceptance/tests/cloud/remote_dev_test.go b/acceptance/tests/cloud/remote_dev_test.go index aa7dbe70c7..457dc4f269 100644 --- a/acceptance/tests/cloud/remote_dev_test.go +++ b/acceptance/tests/cloud/remote_dev_test.go @@ -173,12 +173,12 @@ func TestRemoteDevCloud(t *testing.T) { logger.Log(t, "setting acl permissions for collector and services") aclDir := "../fixtures/bases/cloud/service-intentions" k8s.KubectlApplyK(t, ctx.KubectlOptions(t), aclDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, ctx.KubectlOptions(t), aclDir) }) logger.Log(t, "creating static-server deployment") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") time.Sleep(1 * time.Hour) // TODO: add in test assertions here diff --git a/acceptance/tests/config-entries/config_entries_namespaces_test.go b/acceptance/tests/config-entries/config_entries_namespaces_test.go index 91d0c69df4..a013c99e09 100644 --- a/acceptance/tests/config-entries/config_entries_namespaces_test.go +++ b/acceptance/tests/config-entries/config_entries_namespaces_test.go @@ -102,7 +102,7 @@ func TestControllerNamespaces(t *testing.T) { if err != nil && !strings.Contains(out, "(AlreadyExists)") { require.NoError(t, err) } - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", KubeNS) }) diff --git a/acceptance/tests/config-entries/config_entries_test.go b/acceptance/tests/config-entries/config_entries_test.go index e37e3d6c7f..a36e9baaf5 100644 --- a/acceptance/tests/config-entries/config_entries_test.go +++ b/acceptance/tests/config-entries/config_entries_test.go @@ -86,7 +86,7 @@ func TestController(t *testing.T) { // endpoint fails initially. out, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-k", "../fixtures/bases/crds-oss") require.NoError(r, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-k", "../fixtures/bases/crds-oss") diff --git a/acceptance/tests/connect/connect_external_servers_test.go b/acceptance/tests/connect/connect_external_servers_test.go index a7b0f656bf..c421c1258e 100644 --- a/acceptance/tests/connect/connect_external_servers_test.go +++ b/acceptance/tests/connect/connect_external_servers_test.go @@ -73,11 +73,11 @@ func TestConnectInject_ExternalServers(t *testing.T) { consulCluster.Create(t) logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") } // Check that both static-server and static-client have been injected and now have 2 containers. diff --git a/acceptance/tests/connect/connect_inject_namespaces_test.go b/acceptance/tests/connect/connect_inject_namespaces_test.go index f848594cd2..6fb493ce17 100644 --- a/acceptance/tests/connect/connect_inject_namespaces_test.go +++ b/acceptance/tests/connect/connect_inject_namespaces_test.go @@ -100,12 +100,12 @@ func TestConnectInjectNamespaces(t *testing.T) { logger.Logf(t, "creating namespaces %s and %s", staticServerNamespace, StaticClientNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", staticServerNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", staticServerNamespace) }) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", StaticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Note: this deletion will take longer in cases when the static-client deployment // hasn't yet fully terminated. k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", StaticClientNamespace) @@ -146,11 +146,11 @@ func TestConnectInjectNamespaces(t *testing.T) { } logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") } // Check that both static-server and static-client have been injected and now have 2 containers. @@ -303,7 +303,7 @@ func TestConnectInjectNamespaces_CleanupController(t *testing.T) { logger.Logf(t, "creating namespace %s", StaticClientNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", StaticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", StaticClientNamespace) }) @@ -313,7 +313,7 @@ func TestConnectInjectNamespaces_CleanupController(t *testing.T) { ConfigPath: ctx.KubectlOptions(t).ConfigPath, Namespace: StaticClientNamespace, } - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") logger.Log(t, "waiting for static-client to be registered with Consul") consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) diff --git a/acceptance/tests/connect/connect_inject_test.go b/acceptance/tests/connect/connect_inject_test.go index 199bbf0f1b..c239698d2a 100644 --- a/acceptance/tests/connect/connect_inject_test.go +++ b/acceptance/tests/connect/connect_inject_test.go @@ -107,7 +107,7 @@ func TestConnectInject_CleanupKilledPods(t *testing.T) { consulCluster.Create(t) logger.Log(t, "creating static-client deployment") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") logger.Log(t, "waiting for static-client to be registered with Consul") consulClient, _ := consulCluster.SetupConsulClient(t, secure) @@ -200,8 +200,8 @@ func TestConnectInject_MultiportServices(t *testing.T) { } logger.Log(t, "creating multiport static-server and static-client deployments") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/multiport-app") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject-multiport") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/multiport-app") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject-multiport") // Check that static-client has been injected and now has 2 containers. podList, err := ctx.KubernetesClient(t).CoreV1().Pods(ctx.KubectlOptions(t).Namespace).List(context.Background(), metav1.ListOptions{ @@ -260,7 +260,7 @@ func TestConnectInject_MultiportServices(t *testing.T) { // pod to static-server. // Deploy static-server. - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") // For outbound connections from the multi port pod, only intentions from the first service in the multiport // pod need to be created, since all upstream connections are made through the first service's envoy proxy. diff --git a/acceptance/tests/connect/permissive_mtls_test.go b/acceptance/tests/connect/permissive_mtls_test.go index 1dcc6fe911..d07c44ae2f 100644 --- a/acceptance/tests/connect/permissive_mtls_test.go +++ b/acceptance/tests/connect/permissive_mtls_test.go @@ -58,7 +58,7 @@ func deployNonMeshClient(t *testing.T, ch connhelper.ConnectHelper) { t.Helper() logger.Log(t, "Creating static-client deployment with connect-inject=false") - k8s.DeployKustomize(t, ch.Ctx.KubectlOptions(t), ch.Cfg.NoCleanupOnFailure, ch.Cfg.DebugDirectory, "../fixtures/bases/static-client") + k8s.DeployKustomize(t, ch.Ctx.KubectlOptions(t), ch.Cfg.NoCleanupOnFailure, ch.Cfg.NoCleanup, ch.Cfg.DebugDirectory, "../fixtures/bases/static-client") requirePodContainers(t, ch, "app=static-client", 1) } @@ -66,7 +66,7 @@ func deployStaticServer(t *testing.T, cfg *config.TestConfig, ch connhelper.Conn t.Helper() logger.Log(t, "Creating static-server deployment with connect-inject=true") - k8s.DeployKustomize(t, ch.Ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ch.Ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") requirePodContainers(t, ch, "app=static-server", 2) } diff --git a/acceptance/tests/consul-dns/consul_dns_test.go b/acceptance/tests/consul-dns/consul_dns_test.go index c33de7747d..84741175af 100644 --- a/acceptance/tests/consul-dns/consul_dns_test.go +++ b/acceptance/tests/consul-dns/consul_dns_test.go @@ -65,7 +65,7 @@ func TestConsulDNS(t *testing.T) { "run", "-it", dnsPodName, "--restart", "Never", "--image", "anubhavmishra/tiny-tools", "--", "dig", fmt.Sprintf("@%s-consul-dns", releaseName), "consul.service.consul", } - helpers.Cleanup(t, suite.Config().NoCleanupOnFailure, func() { + helpers.Cleanup(t, suite.Config().NoCleanupOnFailure, suite.Config().NoCleanup, func() { // Note: this delete command won't wait for pods to be fully terminated. // This shouldn't cause any test pollution because the underlying // objects are deployments, and so when other tests create these diff --git a/acceptance/tests/example/example_test.go b/acceptance/tests/example/example_test.go index b324ac31fe..07b04d6097 100644 --- a/acceptance/tests/example/example_test.go +++ b/acceptance/tests/example/example_test.go @@ -44,7 +44,7 @@ func TestExample(t *testing.T) { k8s.KubectlApply(t, ctx.KubectlOptions(t), "path/to/config") // Clean up any Kubernetes resources you have created - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDelete(t, ctx.KubectlOptions(t), "path/to/config") }) diff --git a/acceptance/tests/ingress-gateway/ingress_gateway_namespaces_test.go b/acceptance/tests/ingress-gateway/ingress_gateway_namespaces_test.go index ec4878df04..9edb1db010 100644 --- a/acceptance/tests/ingress-gateway/ingress_gateway_namespaces_test.go +++ b/acceptance/tests/ingress-gateway/ingress_gateway_namespaces_test.go @@ -69,7 +69,7 @@ func TestIngressGatewaySingleNamespace(t *testing.T) { logger.Logf(t, "creating Kubernetes namespace %s", testNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", testNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", testNamespace) }) @@ -80,12 +80,12 @@ func TestIngressGatewaySingleNamespace(t *testing.T) { } logger.Logf(t, "creating server in %s namespace", testNamespace) - k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") // We use the static-client pod so that we can make calls to the ingress gateway // via kubectl exec without needing a route into the cluster from the test machine. logger.Logf(t, "creating static-client in %s namespace", testNamespace) - k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-client") + k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") // With the cluster up, we can create our ingress-gateway config entry. logger.Log(t, "creating config entry") @@ -188,7 +188,7 @@ func TestIngressGatewayNamespaceMirroring(t *testing.T) { logger.Logf(t, "creating Kubernetes namespace %s", testNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", testNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", testNamespace) }) @@ -199,12 +199,12 @@ func TestIngressGatewayNamespaceMirroring(t *testing.T) { } logger.Logf(t, "creating server in %s namespace", testNamespace) - k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") // We use the static-client pod so that we can make calls to the ingress gateway // via kubectl exec without needing a route into the cluster from the test machine. logger.Logf(t, "creating static-client in %s namespace", testNamespace) - k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-client") + k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) diff --git a/acceptance/tests/ingress-gateway/ingress_gateway_test.go b/acceptance/tests/ingress-gateway/ingress_gateway_test.go index b5df6287b6..d2b3d7193e 100644 --- a/acceptance/tests/ingress-gateway/ingress_gateway_test.go +++ b/acceptance/tests/ingress-gateway/ingress_gateway_test.go @@ -52,12 +52,12 @@ func TestIngressGateway(t *testing.T) { consulCluster.Create(t) logger.Log(t, "creating server") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") // We use the static-client pod so that we can make calls to the ingress gateway // via kubectl exec without needing a route into the cluster from the test machine. logger.Log(t, "creating static-client pod") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-client") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") // With the cluster up, we can create our ingress-gateway config entry. logger.Log(t, "creating config entry") diff --git a/acceptance/tests/metrics/metrics_test.go b/acceptance/tests/metrics/metrics_test.go index 2a130f38db..3d40841e36 100644 --- a/acceptance/tests/metrics/metrics_test.go +++ b/acceptance/tests/metrics/metrics_test.go @@ -71,7 +71,7 @@ func TestComponentMetrics(t *testing.T) { // This simulates queries that would be made by a prometheus server that runs externally to the consul // components in the cluster. logger.Log(t, "creating static-client") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-client") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") // Server Metrics metricsOutput, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "exec", "deploy/"+StaticClientName, "--", "curl", "--silent", "--show-error", fmt.Sprintf("http://%s:8500/v1/agent/metrics?format=prometheus", fmt.Sprintf("%s-consul-server.%s.svc", releaseName, ns))) @@ -116,13 +116,13 @@ func TestAppMetrics(t *testing.T) { // Deploy service that will emit app and envoy metrics at merged metrics endpoint logger.Log(t, "creating static-metrics-app") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-metrics-app") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-metrics-app") // Create the static-client deployment so we can use it for in-cluster calls to metrics endpoints. // This simulates queries that would be made by a prometheus server that runs externally to the consul // components in the cluster. logger.Log(t, "creating static-client") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-client") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") // Merged App Metrics podList, err := ctx.KubernetesClient(t).CoreV1().Pods(ns).List(context.Background(), metav1.ListOptions{LabelSelector: "app=static-metrics-app"}) diff --git a/acceptance/tests/partitions/partitions_connect_test.go b/acceptance/tests/partitions/partitions_connect_test.go index aa73c17047..6b103614c7 100644 --- a/acceptance/tests/partitions/partitions_connect_test.go +++ b/acceptance/tests/partitions/partitions_connect_test.go @@ -204,14 +204,14 @@ func TestPartitions_Connect(t *testing.T) { logger.Logf(t, "creating namespaces %s and %s in servers cluster", staticServerNamespace, StaticClientNamespace) k8s.RunKubectl(t, defaultPartitionClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) k8s.RunKubectl(t, defaultPartitionClusterContext.KubectlOptions(t), "create", "ns", StaticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, defaultPartitionClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace, StaticClientNamespace) }) logger.Logf(t, "creating namespaces %s and %s in clients cluster", staticServerNamespace, StaticClientNamespace) k8s.RunKubectl(t, secondaryPartitionClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) k8s.RunKubectl(t, secondaryPartitionClusterContext.KubectlOptions(t), "create", "ns", StaticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, secondaryPartitionClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace, StaticClientNamespace) }) @@ -271,37 +271,37 @@ func TestPartitions_Connect(t *testing.T) { kustomizeDir := "../fixtures/bases/mesh-gateway" k8s.KubectlApplyK(t, defaultPartitionClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, defaultPartitionClusterContext.KubectlOptions(t), kustomizeDir) }) k8s.KubectlApplyK(t, secondaryPartitionClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, secondaryPartitionClusterContext.KubectlOptions(t), kustomizeDir) }) // This section of the tests runs the in-partition networking tests. t.Run("in-partition", func(t *testing.T) { logger.Log(t, "test in-partition networking") logger.Log(t, "creating static-server and static-client deployments in server cluster") - k8s.DeployKustomize(t, defaultPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, defaultPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") } else { - k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") } } logger.Log(t, "creating static-server and static-client deployments in client cluster") - k8s.DeployKustomize(t, secondaryPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") } else { - k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") } } // Check that both static-server and static-client have been injected and now have 2 containers in server cluster. @@ -383,7 +383,7 @@ func TestPartitions_Connect(t *testing.T) { require.NoError(t, err) _, _, err = consulClient.ConfigEntries().Set(intention, &api.WriteOptions{Partition: secondaryPartition}) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { _, err := consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: defaultPartition}) require.NoError(t, err) _, err = consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: secondaryPartition}) @@ -424,25 +424,25 @@ func TestPartitions_Connect(t *testing.T) { t.Run("cross-partition", func(t *testing.T) { logger.Log(t, "test cross-partition networking") logger.Log(t, "creating static-server and static-client deployments in server cluster") - k8s.DeployKustomize(t, defaultPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, defaultPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/default-ns-partition") + k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/default-ns-partition") } else { - k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/ns-partition") + k8s.DeployKustomize(t, defaultPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/ns-partition") } } logger.Log(t, "creating static-server and static-client deployments in client cluster") - k8s.DeployKustomize(t, secondaryPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/default-ns-default-partition") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/default-ns-default-partition") } else { - k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/ns-default-partition") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-partitions/ns-default-partition") } } // Check that both static-server and static-client have been injected and now have 2 containers in server cluster. @@ -496,14 +496,14 @@ func TestPartitions_Connect(t *testing.T) { if c.destinationNamespace == defaultNamespace { k8s.KubectlApplyK(t, defaultPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/default-partition-default") k8s.KubectlApplyK(t, secondaryPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/secondary-partition-default") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, defaultPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/default-partition-default") k8s.KubectlDeleteK(t, secondaryPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/secondary-partition-default") }) } else { k8s.KubectlApplyK(t, defaultPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/default-partition-ns1") k8s.KubectlApplyK(t, secondaryPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/secondary-partition-ns1") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, defaultPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/default-partition-ns1") k8s.KubectlDeleteK(t, secondaryPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/secondary-partition-ns1") }) @@ -551,7 +551,7 @@ func TestPartitions_Connect(t *testing.T) { intention.Sources[0].Partition = defaultPartition _, _, err = consulClient.ConfigEntries().Set(intention, &api.WriteOptions{Partition: secondaryPartition}) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { _, err := consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: defaultPartition}) require.NoError(t, err) _, err = consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: secondaryPartition}) diff --git a/acceptance/tests/partitions/partitions_gateway_test.go b/acceptance/tests/partitions/partitions_gateway_test.go index 5c85e6725b..acdb81fa65 100644 --- a/acceptance/tests/partitions/partitions_gateway_test.go +++ b/acceptance/tests/partitions/partitions_gateway_test.go @@ -147,14 +147,14 @@ func TestPartitions_Gateway(t *testing.T) { logger.Logf(t, "creating namespaces %s and %s in servers cluster", staticServerNamespace, StaticClientNamespace) k8s.RunKubectl(t, defaultPartitionClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) k8s.RunKubectl(t, defaultPartitionClusterContext.KubectlOptions(t), "create", "ns", StaticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, defaultPartitionClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace, StaticClientNamespace) }) logger.Logf(t, "creating namespaces %s and %s in clients cluster", staticServerNamespace, StaticClientNamespace) k8s.RunKubectl(t, secondaryPartitionClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) k8s.RunKubectl(t, secondaryPartitionClusterContext.KubectlOptions(t), "create", "ns", StaticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, secondaryPartitionClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace, StaticClientNamespace) }) @@ -202,12 +202,12 @@ func TestPartitions_Gateway(t *testing.T) { kustomizeDir := "../fixtures/cases/api-gateways/mesh" k8s.KubectlApplyK(t, defaultPartitionClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, defaultPartitionClusterContext.KubectlOptions(t), kustomizeDir) }) k8s.KubectlApplyK(t, secondaryPartitionClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, secondaryPartitionClusterContext.KubectlOptions(t), kustomizeDir) }) @@ -216,12 +216,12 @@ func TestPartitions_Gateway(t *testing.T) { // Since we're deploying the gateway in the secondary cluster, we create the static client // in the secondary as well. logger.Log(t, "creating static-client pod in secondary partition cluster") - k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-client") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") logger.Log(t, "creating api-gateway resources") out, err := k8s.RunKubectlAndGetOutputE(t, secondaryPartitionClusterStaticServerOpts, "apply", "-k", "../fixtures/bases/api-gateway") require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, secondaryPartitionClusterStaticServerOpts, "delete", "-k", "../fixtures/bases/api-gateway") @@ -253,7 +253,7 @@ func TestPartitions_Gateway(t *testing.T) { t.Run("in-partition", func(t *testing.T) { logger.Log(t, "test in-partition networking") logger.Log(t, "creating target server in secondary partition cluster") - k8s.DeployKustomize(t, secondaryPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, secondaryPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "patching route to target server") k8s.RunKubectl(t, secondaryPartitionClusterStaticServerOpts, "patch", "httproute", "http-route", "-p", `{"spec":{"rules":[{"backendRefs":[{"group":"consul.hashicorp.com","kind":"MeshService","name":"mesh-service","port":80}]}]}}`, "--type=merge") @@ -277,7 +277,7 @@ func TestPartitions_Gateway(t *testing.T) { logger.Log(t, "creating intention") _, _, err = consulClient.ConfigEntries().Set(intention, &api.WriteOptions{Partition: secondaryPartition}) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { _, err = consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: secondaryPartition}) require.NoError(t, err) }) @@ -291,17 +291,17 @@ func TestPartitions_Gateway(t *testing.T) { logger.Log(t, "test cross-partition networking") logger.Log(t, "creating target server in default partition cluster") - k8s.DeployKustomize(t, defaultPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, defaultPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating exported services") k8s.KubectlApplyK(t, defaultPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/default-partition-ns1") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, defaultPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/default-partition-ns1") }) logger.Log(t, "creating local service resolver") k8s.KubectlApplyK(t, secondaryPartitionClusterStaticServerOpts, "../fixtures/cases/api-gateways/resolver") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, secondaryPartitionClusterStaticServerOpts, "../fixtures/cases/api-gateways/resolver") }) @@ -328,7 +328,7 @@ func TestPartitions_Gateway(t *testing.T) { logger.Log(t, "creating intention") _, _, err = consulClient.ConfigEntries().Set(intention, &api.WriteOptions{Partition: defaultPartition}) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { _, err = consulClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{Partition: defaultPartition}) require.NoError(t, err) }) diff --git a/acceptance/tests/partitions/partitions_sync_test.go b/acceptance/tests/partitions/partitions_sync_test.go index 8eaaff099e..da95d7f272 100644 --- a/acceptance/tests/partitions/partitions_sync_test.go +++ b/acceptance/tests/partitions/partitions_sync_test.go @@ -195,13 +195,13 @@ func TestPartitions_Sync(t *testing.T) { logger.Logf(t, "creating namespaces %s in servers cluster", staticServerNamespace) k8s.RunKubectl(t, primaryClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, primaryClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace) }) logger.Logf(t, "creating namespaces %s in clients cluster", staticServerNamespace) k8s.RunKubectl(t, secondaryClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, secondaryClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace) }) @@ -241,9 +241,9 @@ func TestPartitions_Sync(t *testing.T) { logger.Log(t, "creating a static-server with a service") // create service in default partition. - k8s.DeployKustomize(t, primaryStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, primaryStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") // create service in secondary partition. - k8s.DeployKustomize(t, secondaryStaticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, secondaryStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") logger.Log(t, "checking that the service has been synced to Consul") var services map[string][]string diff --git a/acceptance/tests/peering/peering_connect_namespaces_test.go b/acceptance/tests/peering/peering_connect_namespaces_test.go index 622e547091..618248c6a9 100644 --- a/acceptance/tests/peering/peering_connect_namespaces_test.go +++ b/acceptance/tests/peering/peering_connect_namespaces_test.go @@ -166,12 +166,12 @@ func TestPeering_ConnectNamespaces(t *testing.T) { kustomizeMeshDir := "../fixtures/bases/mesh-peering" k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) }) k8s.KubectlApplyK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) }) @@ -198,7 +198,7 @@ func TestPeering_ConnectNamespaces(t *testing.T) { // Create the peering acceptor on the client peer. k8s.KubectlApply(t, staticClientPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-acceptor.yaml") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDelete(t, staticClientPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-acceptor.yaml") }) @@ -214,7 +214,7 @@ func TestPeering_ConnectNamespaces(t *testing.T) { // Create the peering dialer on the server peer. k8s.KubectlApply(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-dialer.yaml") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "delete", "secret", "api-token") k8s.KubectlDelete(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-dialer.yaml") }) @@ -232,13 +232,13 @@ func TestPeering_ConnectNamespaces(t *testing.T) { logger.Logf(t, "creating namespaces %s in server peer", staticServerNamespace) k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace) }) logger.Logf(t, "creating namespaces %s in client peer", staticClientNamespace) k8s.RunKubectl(t, staticClientPeerClusterContext.KubectlOptions(t), "create", "ns", staticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticClientPeerClusterContext.KubectlOptions(t), "delete", "ns", staticClientNamespace) }) @@ -256,26 +256,26 @@ func TestPeering_ConnectNamespaces(t *testing.T) { kustomizeDir := "../fixtures/bases/mesh-gateway" k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeDir) }) k8s.KubectlApplyK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeDir) }) logger.Log(t, "creating static-server in server peer") - k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating static-client deployments in client peer") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { if c.destinationNamespace == defaultNamespace { - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/default-namespace") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/default-namespace") } else { - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/non-default-namespace") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/non-default-namespace") } } // Check that both static-server and static-client have been injected and now have 2 containers. @@ -312,12 +312,12 @@ func TestPeering_ConnectNamespaces(t *testing.T) { logger.Log(t, "creating exported services") if c.destinationNamespace == defaultNamespace { k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/default-namespace") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/default-namespace") }) } else { k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/non-default-namespace") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/non-default-namespace") }) } diff --git a/acceptance/tests/peering/peering_connect_test.go b/acceptance/tests/peering/peering_connect_test.go index a14cf3a805..d92ab59990 100644 --- a/acceptance/tests/peering/peering_connect_test.go +++ b/acceptance/tests/peering/peering_connect_test.go @@ -121,12 +121,12 @@ func TestPeering_Connect(t *testing.T) { kustomizeMeshDir := "../fixtures/bases/mesh-peering" k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) }) k8s.KubectlApplyK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) }) @@ -153,7 +153,7 @@ func TestPeering_Connect(t *testing.T) { // Create the peering acceptor on the client peer. k8s.KubectlApply(t, staticClientPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-acceptor.yaml") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDelete(t, staticClientPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-acceptor.yaml") }) @@ -169,7 +169,7 @@ func TestPeering_Connect(t *testing.T) { // Create the peering dialer on the server peer. k8s.KubectlApply(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-dialer.yaml") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "delete", "secret", "api-token") k8s.KubectlDelete(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-dialer.yaml") }) @@ -187,13 +187,13 @@ func TestPeering_Connect(t *testing.T) { logger.Logf(t, "creating namespaces %s in server peer", staticServerNamespace) k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace) }) logger.Logf(t, "creating namespaces %s in client peer", staticClientNamespace) k8s.RunKubectl(t, staticClientPeerClusterContext.KubectlOptions(t), "create", "ns", staticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticClientPeerClusterContext.KubectlOptions(t), "delete", "ns", staticClientNamespace) }) @@ -203,23 +203,23 @@ func TestPeering_Connect(t *testing.T) { kustomizeDir := "../fixtures/bases/mesh-gateway" k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeDir) }) k8s.KubectlApplyK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeDir) }) logger.Log(t, "creating static-server in server peer") - k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating static-client deployments in client peer") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/default") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/default") } // Check that both static-server and static-client have been injected and now have 2 containers. podList, err := staticServerPeerClusterContext.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), metav1.ListOptions{ @@ -249,7 +249,7 @@ func TestPeering_Connect(t *testing.T) { logger.Log(t, "creating exported services") k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/default") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/default") }) diff --git a/acceptance/tests/peering/peering_gateway_test.go b/acceptance/tests/peering/peering_gateway_test.go index 17824b8e69..3ba04980a9 100644 --- a/acceptance/tests/peering/peering_gateway_test.go +++ b/acceptance/tests/peering/peering_gateway_test.go @@ -113,12 +113,12 @@ func TestPeering_Gateway(t *testing.T) { kustomizeMeshDir := "../fixtures/bases/mesh-peering" k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) }) k8s.KubectlApplyK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeMeshDir) }) @@ -145,7 +145,7 @@ func TestPeering_Gateway(t *testing.T) { // Create the peering acceptor on the client peer. k8s.KubectlApply(t, staticClientPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-acceptor.yaml") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDelete(t, staticClientPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-acceptor.yaml") }) @@ -161,7 +161,7 @@ func TestPeering_Gateway(t *testing.T) { // Create the peering dialer on the server peer. k8s.KubectlApply(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-dialer.yaml") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "delete", "secret", "api-token") k8s.KubectlDelete(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/bases/peering/peering-dialer.yaml") }) @@ -179,13 +179,13 @@ func TestPeering_Gateway(t *testing.T) { logger.Logf(t, "creating namespaces %s in server peer", staticServerNamespace) k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "create", "ns", staticServerNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticServerPeerClusterContext.KubectlOptions(t), "delete", "ns", staticServerNamespace) }) logger.Logf(t, "creating namespaces %s in client peer", staticClientNamespace) k8s.RunKubectl(t, staticClientPeerClusterContext.KubectlOptions(t), "create", "ns", staticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, staticClientPeerClusterContext.KubectlOptions(t), "delete", "ns", staticClientNamespace) }) @@ -195,12 +195,12 @@ func TestPeering_Gateway(t *testing.T) { kustomizeDir := "../fixtures/cases/api-gateways/mesh" k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), kustomizeDir) }) k8s.KubectlApplyK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticClientPeerClusterContext.KubectlOptions(t), kustomizeDir) }) @@ -209,21 +209,21 @@ func TestPeering_Gateway(t *testing.T) { // Since we're deploying the gateway in the secondary cluster, we create the static client // in the secondary as well. logger.Log(t, "creating static-client pod in client peer") - k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/non-default-namespace") + k8s.DeployKustomize(t, staticClientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-peers/non-default-namespace") logger.Log(t, "creating static-server in server peer") - k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating exported services") k8s.KubectlApplyK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/non-default-namespace") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticServerPeerClusterContext.KubectlOptions(t), "../fixtures/cases/crd-peers/non-default-namespace") }) logger.Log(t, "creating api-gateway resources in client peer") out, err := k8s.RunKubectlAndGetOutputE(t, staticClientOpts, "apply", "-k", "../fixtures/bases/api-gateway") require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, staticClientOpts, "delete", "-k", "../fixtures/bases/api-gateway") @@ -253,7 +253,7 @@ func TestPeering_Gateway(t *testing.T) { logger.Log(t, "creating local service resolver") k8s.KubectlApplyK(t, staticClientOpts, "../fixtures/cases/api-gateways/peer-resolver") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, staticClientOpts, "../fixtures/cases/api-gateways/peer-resolver") }) @@ -280,7 +280,7 @@ func TestPeering_Gateway(t *testing.T) { logger.Log(t, "creating intention") _, _, err = staticServerPeerClient.ConfigEntries().Set(intention, &api.WriteOptions{}) require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { _, err = staticServerPeerClient.ConfigEntries().Delete(api.ServiceIntentions, staticServerName, &api.WriteOptions{}) require.NoError(t, err) }) diff --git a/acceptance/tests/sync/sync_catalog_namespaces_test.go b/acceptance/tests/sync/sync_catalog_namespaces_test.go index 7634220b6b..67123d6e4f 100644 --- a/acceptance/tests/sync/sync_catalog_namespaces_test.go +++ b/acceptance/tests/sync/sync_catalog_namespaces_test.go @@ -97,12 +97,12 @@ func TestSyncCatalogNamespaces(t *testing.T) { logger.Logf(t, "creating namespace %s", staticServerNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", staticServerNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", staticServerNamespace) }) logger.Log(t, "creating a static-server with a service") - k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, staticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) diff --git a/acceptance/tests/sync/sync_catalog_test.go b/acceptance/tests/sync/sync_catalog_test.go index 2ca8b1ee1f..dc30570422 100644 --- a/acceptance/tests/sync/sync_catalog_test.go +++ b/acceptance/tests/sync/sync_catalog_test.go @@ -50,7 +50,7 @@ func TestSyncCatalog(t *testing.T) { consulCluster.Create(t) logger.Log(t, "creating a static-server with a service") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), suite.Config().NoCleanupOnFailure, suite.Config().DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), suite.Config().NoCleanupOnFailure, suite.Config().NoCleanup, suite.Config().DebugDirectory, "../fixtures/bases/static-server") consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) @@ -120,7 +120,7 @@ func TestSyncCatalogWithIngress(t *testing.T) { // endpoint fails initially. out, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-k", "../fixtures/bases/ingress") require.NoError(r, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-k", "../fixtures/bases/ingress") @@ -130,7 +130,7 @@ func TestSyncCatalogWithIngress(t *testing.T) { consulCluster.Create(t) logger.Log(t, "creating a static-server with a service") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), suite.Config().NoCleanupOnFailure, suite.Config().DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), suite.Config().NoCleanupOnFailure, suite.Config().NoCleanup, suite.Config().DebugDirectory, "../fixtures/bases/static-server") consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) diff --git a/acceptance/tests/terminating-gateway/terminating_gateway_destinations_test.go b/acceptance/tests/terminating-gateway/terminating_gateway_destinations_test.go index 109975d731..62485c6e44 100644 --- a/acceptance/tests/terminating-gateway/terminating_gateway_destinations_test.go +++ b/acceptance/tests/terminating-gateway/terminating_gateway_destinations_test.go @@ -73,7 +73,7 @@ func TestTerminatingGatewayDestinations(t *testing.T) { // Deploy a static-server that will play the role of an external service. logger.Log(t, "creating static-server deployment") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server-https") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server-https") // If ACLs are enabled we need to update the role of the terminating gateway // with service:write permissions to the static-server service @@ -91,7 +91,7 @@ func TestTerminatingGatewayDestinations(t *testing.T) { // Deploy the static client logger.Log(t, "deploying static client") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") staticServerIP, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "get", "po", "-l", "app=static-server", `-o=jsonpath={.items[0].status.podIP}`) require.NoError(t, err) diff --git a/acceptance/tests/terminating-gateway/terminating_gateway_namespaces_test.go b/acceptance/tests/terminating-gateway/terminating_gateway_namespaces_test.go index 7ad9f7da10..73250ea810 100644 --- a/acceptance/tests/terminating-gateway/terminating_gateway_namespaces_test.go +++ b/acceptance/tests/terminating-gateway/terminating_gateway_namespaces_test.go @@ -62,7 +62,7 @@ func TestTerminatingGatewaySingleNamespace(t *testing.T) { logger.Logf(t, "creating Kubernetes namespace %s", testNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", testNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", testNamespace) }) @@ -74,7 +74,7 @@ func TestTerminatingGatewaySingleNamespace(t *testing.T) { // Deploy a static-server that will play the role of an external service. logger.Log(t, "creating static-server deployment") - k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") // Register the external service. registerExternalService(t, consulClient, testNamespace) @@ -91,7 +91,7 @@ func TestTerminatingGatewaySingleNamespace(t *testing.T) { // Deploy the static client. logger.Log(t, "deploying static client") - k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + k8s.DeployKustomize(t, nsK8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") // If ACLs are enabled, test that intentions prevent connections. if c.secure { @@ -159,14 +159,14 @@ func TestTerminatingGatewayNamespaceMirroring(t *testing.T) { logger.Logf(t, "creating Kubernetes namespace %s", testNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", testNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", testNamespace) }) StaticClientNamespace := "ns2" logger.Logf(t, "creating Kubernetes namespace %s", StaticClientNamespace) k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "ns", StaticClientNamespace) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "ns", StaticClientNamespace) }) @@ -183,7 +183,7 @@ func TestTerminatingGatewayNamespaceMirroring(t *testing.T) { // Deploy a static-server that will play the role of an external service. logger.Log(t, "creating static-server deployment") - k8s.DeployKustomize(t, ns1K8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, ns1K8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") // Register the external service registerExternalService(t, consulClient, testNamespace) @@ -200,7 +200,7 @@ func TestTerminatingGatewayNamespaceMirroring(t *testing.T) { // Deploy the static client logger.Log(t, "deploying static client") - k8s.DeployKustomize(t, ns2K8SOptions, cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") + k8s.DeployKustomize(t, ns2K8SOptions, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-namespaces") // If ACLs are enabled, test that intentions prevent connections. if c.secure { diff --git a/acceptance/tests/terminating-gateway/terminating_gateway_test.go b/acceptance/tests/terminating-gateway/terminating_gateway_test.go index 25792e9abb..6e7e95032f 100644 --- a/acceptance/tests/terminating-gateway/terminating_gateway_test.go +++ b/acceptance/tests/terminating-gateway/terminating_gateway_test.go @@ -51,7 +51,7 @@ func TestTerminatingGateway(t *testing.T) { // Deploy a static-server that will play the role of an external service. logger.Log(t, "creating static-server deployment") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/bases/static-server") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") // Once the cluster is up, register the external service, then create the config entry. consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) @@ -71,7 +71,7 @@ func TestTerminatingGateway(t *testing.T) { // Deploy the static client logger.Log(t, "deploying static client") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") // If ACLs are enabled, test that intentions prevent connections. if c.secure { diff --git a/acceptance/tests/vault/vault_namespaces_test.go b/acceptance/tests/vault/vault_namespaces_test.go index 68fa819a84..4a9ca092d0 100644 --- a/acceptance/tests/vault/vault_namespaces_test.go +++ b/acceptance/tests/vault/vault_namespaces_test.go @@ -265,13 +265,13 @@ func TestVault_VaultNamespace(t *testing.T) { // Deploy two services and check that they can talk to each other. logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") } - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") }) k8s.KubectlApplyK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") diff --git a/acceptance/tests/vault/vault_test.go b/acceptance/tests/vault/vault_test.go index 47d58b68c5..9dab0a3e71 100644 --- a/acceptance/tests/vault/vault_test.go +++ b/acceptance/tests/vault/vault_test.go @@ -350,13 +350,13 @@ func testVault(t *testing.T, testAutoBootstrap bool) { // Deploy two services and check that they can talk to each other. logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") } - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") }) k8s.KubectlApplyK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") diff --git a/acceptance/tests/vault/vault_tls_auto_reload_test.go b/acceptance/tests/vault/vault_tls_auto_reload_test.go index c3a3ae4034..d5d4d33c4c 100644 --- a/acceptance/tests/vault/vault_tls_auto_reload_test.go +++ b/acceptance/tests/vault/vault_tls_auto_reload_test.go @@ -246,13 +246,13 @@ func TestVault_TLSAutoReload(t *testing.T) { // Deploy two services and check that they can talk to each other. logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") if cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") } else { - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-inject") } - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") }) k8s.KubectlApplyK(t, ctx.KubectlOptions(t), "../fixtures/bases/intention") diff --git a/acceptance/tests/vault/vault_wan_fed_test.go b/acceptance/tests/vault/vault_wan_fed_test.go index d8c00b732a..fa63c4d5fb 100644 --- a/acceptance/tests/vault/vault_wan_fed_test.go +++ b/acceptance/tests/vault/vault_wan_fed_test.go @@ -31,6 +31,7 @@ import ( // in the secondary that will treat the Vault server in the primary as an external server. func TestVault_WANFederationViaGateways(t *testing.T) { cfg := suite.Config() + if cfg.UseKind { t.Skipf("Skipping this test because it's currently flaky on kind") } @@ -491,16 +492,18 @@ func TestVault_WANFederationViaGateways(t *testing.T) { logger.Log(t, "creating proxy-defaults config") kustomizeDir := "../fixtures/bases/mesh-gateway" k8s.KubectlApplyK(t, primaryCtx.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, primaryCtx.KubectlOptions(t), kustomizeDir) }) // Check that we can connect services over the mesh gateways. + logger.Log(t, "creating static-server in dc2") - k8s.DeployKustomize(t, secondaryCtx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, secondaryCtx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating static-client in dc1") - k8s.DeployKustomize(t, primaryCtx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") + k8s.DeployKustomize(t, primaryCtx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") logger.Log(t, "creating intention") _, _, err = primaryClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ @@ -517,6 +520,7 @@ func TestVault_WANFederationViaGateways(t *testing.T) { logger.Log(t, "checking that connection is successful") k8s.CheckStaticServerConnectionSuccessful(t, primaryCtx.KubectlOptions(t), StaticClientName, "http://localhost:1234") + } // vaultAddress returns Vault's server URL depending on test configuration. diff --git a/acceptance/tests/wan-federation/wan_federation_gateway_test.go b/acceptance/tests/wan-federation/wan_federation_gateway_test.go index c87ee7197b..6abacda438 100644 --- a/acceptance/tests/wan-federation/wan_federation_gateway_test.go +++ b/acceptance/tests/wan-federation/wan_federation_gateway_test.go @@ -130,25 +130,25 @@ func TestWANFederation_Gateway(t *testing.T) { logger.Log(t, "creating proxy-defaults config in dc1") kustomizeDir := "../fixtures/cases/api-gateways/mesh" k8s.KubectlApplyK(t, primaryContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, primaryContext.KubectlOptions(t), kustomizeDir) }) // these clients are just there so we can exec in and curl on them. logger.Log(t, "creating static-client in dc1") - k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") + k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") logger.Log(t, "creating static-client in dc2") - k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") + k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") t.Run("from primary to secondary", func(t *testing.T) { logger.Log(t, "creating static-server in dc2") - k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating api-gateway resources in dc1") out, err := k8s.RunKubectlAndGetOutputE(t, primaryContext.KubectlOptions(t), "apply", "-k", "../fixtures/bases/api-gateway") require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, primaryContext.KubectlOptions(t), "delete", "-k", "../fixtures/bases/api-gateway") @@ -156,7 +156,7 @@ func TestWANFederation_Gateway(t *testing.T) { // create a service resolver for doing cross-dc redirects. k8s.KubectlApplyK(t, secondaryContext.KubectlOptions(t), "../fixtures/cases/api-gateways/dc1-to-dc2-resolver") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, secondaryContext.KubectlOptions(t), "../fixtures/cases/api-gateways/dc1-to-dc2-resolver") }) @@ -170,12 +170,12 @@ func TestWANFederation_Gateway(t *testing.T) { t.Run("from secondary to primary", func(t *testing.T) { // Check that we can connect services over the mesh gateways logger.Log(t, "creating static-server in dc1") - k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating api-gateway resources in dc2") out, err := k8s.RunKubectlAndGetOutputE(t, secondaryContext.KubectlOptions(t), "apply", "-k", "../fixtures/bases/api-gateway") require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { // Ignore errors here because if the test ran as expected // the custom resources will have been deleted. k8s.RunKubectlAndGetOutputE(t, secondaryContext.KubectlOptions(t), "delete", "-k", "../fixtures/bases/api-gateway") @@ -183,7 +183,7 @@ func TestWANFederation_Gateway(t *testing.T) { // create a service resolver for doing cross-dc redirects. k8s.KubectlApplyK(t, secondaryContext.KubectlOptions(t), "../fixtures/cases/api-gateways/dc2-to-dc1-resolver") - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, secondaryContext.KubectlOptions(t), "../fixtures/cases/api-gateways/dc2-to-dc1-resolver") }) diff --git a/acceptance/tests/wan-federation/wan_federation_test.go b/acceptance/tests/wan-federation/wan_federation_test.go index e7a128887e..bae8e8e9da 100644 --- a/acceptance/tests/wan-federation/wan_federation_test.go +++ b/acceptance/tests/wan-federation/wan_federation_test.go @@ -157,16 +157,16 @@ func TestWANFederation(t *testing.T) { logger.Log(t, "creating proxy-defaults config") kustomizeDir := "../fixtures/bases/mesh-gateway" k8s.KubectlApplyK(t, secondaryContext.KubectlOptions(t), kustomizeDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, func() { + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { k8s.KubectlDeleteK(t, secondaryContext.KubectlOptions(t), kustomizeDir) }) // Check that we can connect services over the mesh gateways logger.Log(t, "creating static-server in dc2") - k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating static-client in dc1") - k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") + k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") if c.secure { logger.Log(t, "creating intention") diff --git a/go.work b/go.work new file mode 100644 index 0000000000..318dd011c0 --- /dev/null +++ b/go.work @@ -0,0 +1,11 @@ + +use ( + ./acceptance + ./charts + ./cli + ./control-plane + ./control-plane/cni + ./hack/aws-acceptance-test-cleanup + ./hack/copy-crds-to-chart + ./hack/helm-reference-gen +) diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 0000000000..2961d25a18 --- /dev/null +++ b/go.work.sum @@ -0,0 +1,352 @@ +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= +cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= +cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= +cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= +cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= +cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= +cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= +cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= +cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= +cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= +cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= +cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= +cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= +cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= +cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= +cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= +cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= +cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= +cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= +cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= +cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= +cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= +cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= +cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= +cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= +cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= +cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= +cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= +cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= +cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= +cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= +cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= +cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= +cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= +cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= +cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= +cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= +cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= +cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= +cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= +cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= +cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= +cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= +cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= +cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= +cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= +cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= +cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= +cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= +cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= +cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= +cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= +cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= +cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= +cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= +cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= +cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= +cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= +cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= +cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= +cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= +cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= +cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= +cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= +cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= +cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= +cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= +cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= +cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= +cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= +cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= +cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= +cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= +cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= +cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= +cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= +cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= +cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= +cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= +cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= +cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= +cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= +cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= +cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= +cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= +cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= +cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= +cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= +cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= +cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= +cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= +cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= +cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= +cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= +cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= +cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= +cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= +cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= +cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= +cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= +cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= +cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= +cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= +cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= +cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= +cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= +cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= +cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= +cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= +cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= +cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= +cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= +cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= +cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= +cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= +cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= +cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= +cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= +cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= +cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= +cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= +cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= +cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= +cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= +cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= +cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= +cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= +cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= +github.com/Azure/azure-sdk-for-go v46.0.0+incompatible h1:4qlEOCDcDQZTGczYGzbGYCdJfVpZLIs8AEo5+MoXBPw= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.1 h1:bvUhZciHydpBxBmCheUgxxbSwJy7xcfjkUsjUcqSojc= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= +github.com/ahmetb/gen-crd-api-reference-docs v0.3.0/go.mod h1:TdjdkYhlOifCQWPs1UdTma97kQQMozf5h26hTuG70u8= +github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/gobuffalo/flect v0.3.0/go.mod h1:5pf3aGnsvqvCj50AVni7mJJF8ICxGZ8HomberC3pXLE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= +github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= +github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= +github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= +github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= +github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= +github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= +github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= +github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= +github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= +github.com/onsi/gomega v1.24.2/go.mod h1:gs3J10IS7Z7r7eXRoNJIrNqU4ToQukCJhFtKrWgHWnk= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/vmware/govmomi v0.20.3 h1:gpw/0Ku+6RgF3jsi7fnCLmlcikBHfKBCUcu1qgc16OU= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= +go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= +go.etcd.io/etcd/client/v2 v2.305.5/go.mod h1:zQjKllfqfBVyVStbt4FaosoX2iYd8fV/GRy/PbowgP4= +go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c= +go.etcd.io/etcd/pkg/v3 v3.5.5/go.mod h1:6ksYFxttiUGzC2uxyqiyOEvhAiD0tuIqSZkX3TyPdaE= +go.etcd.io/etcd/raft/v3 v3.5.5/go.mod h1:76TA48q03g1y1VpTue92jZLr9lIHKUNcYdZOOGyx8rI= +go.etcd.io/etcd/server/v3 v3.5.5/go.mod h1:rZ95vDw/jrvsbj9XpTqPrTAB9/kzchVdhRirySPkUBc= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= +go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0/go.mod h1:Krqnjl22jUJ0HgMzw5eveuCvFDXY4nSYb4F8t5gdrag= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0/go.mod h1:OfUCyyIiDvNXHWpcWgbF+MWvqPZiNa3YDEnivcnYsV0= +go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= +go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI= +go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= +go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= +go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= +google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= +google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= +google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= +google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= +google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= +google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= +google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= +google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +k8s.io/apiserver v0.26.3 h1:blBpv+yOiozkPH2aqClhJmJY+rp53Tgfac4SKPDJnU4= +k8s.io/apiserver v0.26.3/go.mod h1:CJe/VoQNcXdhm67EvaVjYXxR3QyfwpceKPuPaeLibTA= +k8s.io/code-generator v0.26.3/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI= +k8s.io/gengo v0.0.0-20201203183100-97869a43a9d9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= +k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kms v0.26.3/go.mod h1:69qGnf1NsFOQP07fBYqNLZklqEHSJF024JqYCaeVxHg= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.36/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo= +sigs.k8s.io/controller-tools v0.11.4/go.mod h1:qcfX7jfcfYD/b7lAhvqAyTbt/px4GpvN88WKLFFv7p8= +sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= From 8b45de8b153c158d68c972b9e872acc1e4b06825 Mon Sep 17 00:00:00 2001 From: skpratt Date: Thu, 20 Jul 2023 23:43:57 -0500 Subject: [PATCH 082/120] Differentiate FIPS linux package names (#2599) --- .github/workflows/build.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1d7942617d..12904b3070 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -79,8 +79,8 @@ jobs: - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402", pkg_suffix: "-fips" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } # control-plane @@ -96,8 +96,8 @@ jobs: - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402", pkg_suffix: "-fips" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } # consul-cni @@ -112,8 +112,8 @@ jobs: - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402", pkg_suffix: "-fips" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } @@ -174,7 +174,7 @@ jobs: if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} uses: hashicorp/actions-packaging-linux@v1 with: - name: consul-k8s + name: consul-k8s${{ matrix.pkg_suffix }} description: "consul-k8s provides a cli interface to first-class integrations between Consul and Kubernetes." arch: ${{ matrix.goarch }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} From efa2be8fe702bbbdbbc86fcecc8ba33a28c9f650 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Fri, 21 Jul 2023 09:47:53 -0700 Subject: [PATCH 083/120] added make target for checking for hashicorppreview (#2603) * added make target for checking for hashicorppreview * added check to prepare-release make target --- Makefile | 10 ++++++++-- .../build-support/scripts/check-hashicorppreview.sh | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) create mode 100755 control-plane/build-support/scripts/check-hashicorppreview.sh diff --git a/Makefile b/Makefile index 1d62035dbb..4289b81b9b 100644 --- a/Makefile +++ b/Makefile @@ -97,6 +97,10 @@ terraform-fmt: @terraform fmt -recursive .PHONY: terraform-fmt +# Check for hashicorppreview containers +check-preview-containers: + @source $(CURDIR)/control-plane/build-support/scripts/check-hashicorppreview.sh + # ===========> CLI Targets cli-dev: @@ -221,7 +225,7 @@ aks-test-packages: check-env: @printenv | grep "CONSUL_K8S" -prepare-release: ## Sets the versions, updates changelog to prepare this repository to release +prepare-release-script: ## Sets the versions, updates changelog to prepare this repository to release ifndef CONSUL_K8S_RELEASE_VERSION $(error CONSUL_K8S_RELEASE_VERSION is required) endif @@ -234,7 +238,9 @@ endif ifndef CONSUL_K8S_CONSUL_VERSION $(error CONSUL_K8S_CONSUL_VERSION is required) endif - source $(CURDIR)/control-plane/build-support/scripts/functions.sh; prepare_release $(CURDIR) $(CONSUL_K8S_RELEASE_VERSION) "$(CONSUL_K8S_RELEASE_DATE)" $(CONSUL_K8S_LAST_RELEASE_GIT_TAG) $(CONSUL_K8S_CONSUL_VERSION) $(CONSUL_K8S_CONSUL_DATAPLANE_VERSION) $(CONSUL_K8S_PRERELEASE_VERSION) + @source $(CURDIR)/control-plane/build-support/scripts/functions.sh; prepare_release $(CURDIR) $(CONSUL_K8S_RELEASE_VERSION) "$(CONSUL_K8S_RELEASE_DATE)" $(CONSUL_K8S_LAST_RELEASE_GIT_TAG) $(CONSUL_K8S_CONSUL_VERSION) $(CONSUL_K8S_CONSUL_DATAPLANE_VERSION) $(CONSUL_K8S_PRERELEASE_VERSION); \ + +prepare-release: prepare-release-script check-preview-containers prepare-dev: ifndef CONSUL_K8S_RELEASE_VERSION diff --git a/control-plane/build-support/scripts/check-hashicorppreview.sh b/control-plane/build-support/scripts/check-hashicorppreview.sh new file mode 100755 index 0000000000..cd694dad93 --- /dev/null +++ b/control-plane/build-support/scripts/check-hashicorppreview.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 +echo "Checking charts for hashicorpreview images. . ." +if grep -rnw -e 'hashicorppreview' './charts'; then + echo Charts contain hashicorppreview images. If this is intended for release, please remove the preview images. +else + echo Charts do not contain hashicorpreview images, ready for release! +fi \ No newline at end of file From e2adf6fe0ada638295ae2fdeadba054abf65cfe6 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Fri, 21 Jul 2023 13:13:34 -0400 Subject: [PATCH 084/120] Increase golangci-lint timeout to 10m (#2621) This is meant to solve for recurrent timeouts in several steps, particularly `golangci-lint-control-plane` and `golang-ci-lint-cli`. An accompanying change in `consul-k8s-workflows` should disable caching until the (unclear) root of the issue can be resolved, or we can disable or clear cache in a more targeted way that solves for these cases. --- .golangci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.golangci.yml b/.golangci.yml index 142f5c2722..dcad005d10 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -34,4 +34,4 @@ linters-settings: simplify: true run: - timeout: 5m + timeout: 10m From 1690fe297fdd02afafeb3713b978a30cf846b86e Mon Sep 17 00:00:00 2001 From: Paul Glass Date: Mon, 24 Jul 2023 10:38:31 -0500 Subject: [PATCH 085/120] Fix TestAPIGateway_GatewayClassConfig (#2631) * Fix TestAPIGateway_GatewayClassConfig * Remove stray files from bad merge --- .../api_gateway_gatewayclassconfig_test.go | 20 - go.work | 11 - go.work.sum | 352 ------------------ 3 files changed, 383 deletions(-) delete mode 100644 go.work delete mode 100644 go.work.sum diff --git a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go index ffe0424ef1..89ba07a1e7 100644 --- a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go +++ b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go @@ -63,22 +63,6 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { k8sClient := ctx.ControllerRuntimeClient(t) - //create clean namespace - err = k8sClient.Create(context.Background(), &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - }, - }) - require.NoError(t, err) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { - logger.Log(t, "deleting gateway namesapce") - k8sClient.Delete(context.Background(), &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: namespace, - }, - }) - }) - // create a GatewayClassConfig with configuration set gatewayClassConfigName := "gateway-class-config" gatewayClassConfig := &v1alpha1.GatewayClassConfig{ @@ -144,10 +128,6 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { logger.Log(t, "creating controlled gateway") gateway := createGateway(t, k8sClient, gatewayName, namespace, gatewayClassName, certificateName) - // make sure it exists - logger.Log(t, "checking that gateway one is synchronized to Consul") - checkConsulExists(t, consulClient, api.APIGateway, gatewayName) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all gateways") k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.Gateway{}, client.InNamespace(namespace)) diff --git a/go.work b/go.work deleted file mode 100644 index 318dd011c0..0000000000 --- a/go.work +++ /dev/null @@ -1,11 +0,0 @@ - -use ( - ./acceptance - ./charts - ./cli - ./control-plane - ./control-plane/cni - ./hack/aws-acceptance-test-cleanup - ./hack/copy-crds-to-chart - ./hack/helm-reference-gen -) diff --git a/go.work.sum b/go.work.sum deleted file mode 100644 index 2961d25a18..0000000000 --- a/go.work.sum +++ /dev/null @@ -1,352 +0,0 @@ -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I= -cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys= -cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY= -cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E= -cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ= -cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw= -cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE= -cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8= -cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8= -cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc= -cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8= -cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E= -cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k= -cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08= -cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw= -cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E= -cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU= -cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss= -cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g= -cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU= -cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU= -cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc= -cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q= -cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8= -cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU= -cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s= -cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA= -cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs= -cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo= -cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= -cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= -cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w= -cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA= -cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s= -cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8= -cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE= -cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE= -cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8= -cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM= -cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs= -cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4= -cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c= -cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c= -cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww= -cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ= -cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE= -cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4= -cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs= -cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE= -cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY= -cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU= -cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M= -cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY= -cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg= -cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE= -cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c= -cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0= -cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg= -cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw= -cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw= -cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y= -cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo= -cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE= -cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0= -cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74= -cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4= -cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE= -cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI= -cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY= -cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo= -cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M= -cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo= -cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA= -cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY= -cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I= -cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM= -cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo= -cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw= -cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM= -cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY= -cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU= -cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ= -cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI= -cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ= -cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc= -cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw= -cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs= -cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk= -cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc= -cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs= -cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4= -cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM= -cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c= -cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac= -cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ= -cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ= -cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI= -cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA= -cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14= -cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg= -cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc= -cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU= -cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0= -cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag= -cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk= -cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s= -cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4= -cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA= -cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A= -cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M= -cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI= -cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y= -cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4= -cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw= -cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c= -cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc= -cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM= -cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk= -cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos= -cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ= -cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU= -cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0= -cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY= -cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY= -cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes= -cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg= -cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng= -cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= -github.com/Azure/azure-sdk-for-go v46.0.0+incompatible h1:4qlEOCDcDQZTGczYGzbGYCdJfVpZLIs8AEo5+MoXBPw= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.1 h1:bvUhZciHydpBxBmCheUgxxbSwJy7xcfjkUsjUcqSojc= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/ahmetb/gen-crd-api-reference-docs v0.3.0/go.mod h1:TdjdkYhlOifCQWPs1UdTma97kQQMozf5h26hTuG70u8= -github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/gobuffalo/flect v0.3.0/go.mod h1:5pf3aGnsvqvCj50AVni7mJJF8ICxGZ8HomberC3pXLE= -github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/cel-go v0.12.6/go.mod h1:Jk7ljRzLBhkmiAwBoUxB1sZSCVBAzkqPF25olK/iRDw= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8= -github.com/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A= -github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= -github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= -github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= -github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= -github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= -github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc= -github.com/onsi/ginkgo/v2 v2.6.1/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= -github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= -github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg= -github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM= -github.com/onsi/gomega v1.24.2/go.mod h1:gs3J10IS7Z7r7eXRoNJIrNqU4ToQukCJhFtKrWgHWnk= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= -github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= -github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/vmware/govmomi v0.20.3 h1:gpw/0Ku+6RgF3jsi7fnCLmlcikBHfKBCUcu1qgc16OU= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd/api/v3 v3.5.5/go.mod h1:KFtNaxGDw4Yx/BA4iPPwevUTAuqcsPxzyX8PHydchN8= -go.etcd.io/etcd/client/pkg/v3 v3.5.5/go.mod h1:ggrwbk069qxpKPq8/FKkQ3Xq9y39kbFR4LnKszpRXeQ= -go.etcd.io/etcd/client/v2 v2.305.5/go.mod h1:zQjKllfqfBVyVStbt4FaosoX2iYd8fV/GRy/PbowgP4= -go.etcd.io/etcd/client/v3 v3.5.5/go.mod h1:aApjR4WGlSumpnJ2kloS75h6aHUmAyaPLjHMxpc7E7c= -go.etcd.io/etcd/pkg/v3 v3.5.5/go.mod h1:6ksYFxttiUGzC2uxyqiyOEvhAiD0tuIqSZkX3TyPdaE= -go.etcd.io/etcd/raft/v3 v3.5.5/go.mod h1:76TA48q03g1y1VpTue92jZLr9lIHKUNcYdZOOGyx8rI= -go.etcd.io/etcd/server/v3 v3.5.5/go.mod h1:rZ95vDw/jrvsbj9XpTqPrTAB9/kzchVdhRirySPkUBc= -go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.25.0/go.mod h1:E5NNboN0UqSAki0Atn9kVwaN7I+l25gGxDqBueo/74E= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.35.0/go.mod h1:h8TWwRAhQpOd0aM5nYsRD8+flnkj+526GEIVlarH7eY= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0/go.mod h1:9NiG9I2aHTKkcxqCILhjtyNA1QEiCjdBACv4IvrFQ+c= -go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU= -go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.10.0/go.mod h1:78XhIg8Ht9vR4tbLNUhXsiOnE2HOuSeKAiAcoVQEpOY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.0.1/go.mod h1:Kv8liBeVNFkkkbilbgWRpV+wWuu+H5xdOT6HAgd30iw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.10.0/go.mod h1:Krqnjl22jUJ0HgMzw5eveuCvFDXY4nSYb4F8t5gdrag= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.0.1/go.mod h1:xOvWoTOrQjxjW61xtOmD/WKGRYb/P4NzRo3bs65U6Rk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.10.0/go.mod h1:OfUCyyIiDvNXHWpcWgbF+MWvqPZiNa3YDEnivcnYsV0= -go.opentelemetry.io/otel/metric v0.31.0/go.mod h1:ohmwj9KTSIeBnDBm/ZwH2PSZxZzoOaG2xZeekTRzL5A= -go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI= -go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= -go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= -go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk= -go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= -go.opentelemetry.io/proto/otlp v0.9.0/go.mod h1:1vKfU9rv61e9EVGthD1zNvUbiwPcimSsOPU9brfSHJg= -go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= -golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= -golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= -golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY= -google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI= -google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0= -google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE= -google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= -google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw= -google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA= -google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= -google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -k8s.io/apiserver v0.26.3 h1:blBpv+yOiozkPH2aqClhJmJY+rp53Tgfac4SKPDJnU4= -k8s.io/apiserver v0.26.3/go.mod h1:CJe/VoQNcXdhm67EvaVjYXxR3QyfwpceKPuPaeLibTA= -k8s.io/code-generator v0.26.3/go.mod h1:ryaiIKwfxEJEaywEzx3dhWOydpVctKYbqLajJf0O8dI= -k8s.io/gengo v0.0.0-20201203183100-97869a43a9d9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20220902162205-c0856e24416d/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= -k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= -k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kms v0.26.3/go.mod h1:69qGnf1NsFOQP07fBYqNLZklqEHSJF024JqYCaeVxHg= -k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= -k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.36/go.mod h1:WxjusMwXlKzfAs4p9km6XJRndVt2FROgMVCE4cdohFo= -sigs.k8s.io/controller-tools v0.11.4/go.mod h1:qcfX7jfcfYD/b7lAhvqAyTbt/px4GpvN88WKLFFv7p8= -sigs.k8s.io/structured-merge-diff v1.0.1-0.20191108220359-b1b620dd3f06 h1:zD2IemQ4LmOcAumeiyDWXKUI2SO0NYDe3H6QGvPOVgU= From 3932e2882837c4db37e6c1acadcc959901b57b62 Mon Sep 17 00:00:00 2001 From: Paul Glass Date: Mon, 24 Jul 2023 11:06:15 -0500 Subject: [PATCH 086/120] Support running with restricted PSA enforcement enabled (part 1) (#2572) Support restricted PSA enforcement in a basic setup. This is enough to get a basic setup with ACLs and TLS working and an acceptance test passing (but does not update every component). On OpenShift, we have the option to set the security context or not. If the security context is unset, then it is set automatically by OpenShift SCCs. However, we prefer to set the security context to avoid useless warnings on OpenShift and to reduce the config difference between OpenShift and plain Kube. By default, OpenShift namespaces have the audit and warn PSA labels set to restricted, so we receive pod security warnings when deploying Consul to OpenShift even though the pods will be able to run. Helm chart changes: * Add a helper to the helm chart to define a "restricted" container security context (when pod security policies are not enabled) * Update the following container securityContexts to use the "restricted" settings (not exhaustive) - gateway-cleanup-job.yaml - gateway-resources-job.yaml - gossip-encryption-autogenerate-job.yaml - server-acl-init-cleanup-job.yaml - only if `.Values.server.containerSecurityContext.server.acl-init` is unset - server-acl-init-job.yaml - only if `.Values.server.containerSecurityContext.server.acl-init` is unset - server-statefulset.yaml: - the locality-init container receives the restricted context - the consul container receives the restricted context only if `.Values.server.containerSecurityContext.server` is unset - tls-init-cleanup-job.yaml - only if `.Values.server.containerSecurityContext.server.tls-init` is unset - tls-init-job.yaml - only if `.Values.server.containerSecurityContext.server.tls-init` is unset - webhook-cert-manager-deployment.yaml Acceptance test changes: * When `-enable-openshift` and `-enable-cni` are set, configure the CNI settings correctly for OpenShift. * Add the `-enable-restricted-psa-enforcement` test flag. When this is set, the tests assume the Consul namespace has restricted PSA enforcement enabled. The tests will deploy the CNI (if enabled) into the `kube-system` namespace. Compatible test cases will deploy applications outside of the Consul namespace. * Update the ConnectHelper to configure the NetworkAttachmentDefinition required to be compatible with the CNI on OpenShift. * Add fixtures for static-client and static-server for OpenShift. This is necessary because the deployment configs must reference the network attachment definition when using the CNI on OpenShift. * Update tests in the `acceptance/tests/connect` directory to either run or skip based on -enable-cni and -enable-openshift --- .changelog/2572.txt | 3 + acceptance/framework/config/config.go | 22 +++- acceptance/framework/config/config_test.go | 1 + .../framework/connhelper/connect_helper.go | 112 ++++++++++++++---- .../framework/consul/helm_cluster_test.go | 6 + .../framework/environment/environment.go | 10 ++ acceptance/framework/flags/flags.go | 14 ++- .../connect/connect_external_servers_test.go | 2 + .../connect/connect_inject_namespaces_test.go | 2 + .../tests/connect/connect_inject_test.go | 30 +++-- .../connect/connect_proxy_lifecycle_test.go | 1 + .../tests/connect/permissive_mtls_test.go | 1 + .../bases/openshift/network-attachment.yaml | 17 +++ .../kustomization.yaml | 8 ++ .../static-client-openshift-inject/patch.yaml | 14 +++ .../kustomization.yaml | 8 ++ .../static-client-openshift-tproxy/patch.yaml | 18 +++ .../kustomization.yaml | 8 ++ .../cases/static-server-openshift/patch.yaml | 42 +++++++ charts/consul/templates/_helpers.tpl | 25 +++- .../templates/connect-inject-deployment.yaml | 1 + .../consul/templates/gateway-cleanup-job.yaml | 1 + .../templates/gateway-resources-job.yaml | 1 + .../gossip-encryption-autogenerate-job.yaml | 1 + .../server-acl-init-cleanup-job.yaml | 3 + .../consul/templates/server-acl-init-job.yaml | 3 + .../consul/templates/server-statefulset.yaml | 5 +- .../templates/tls-init-cleanup-job.yaml | 3 + charts/consul/templates/tls-init-job.yaml | 3 + .../webhook-cert-manager-deployment.yaml | 1 + .../consul/test/unit/server-statefulset.bats | 70 ++++++++++- 31 files changed, 397 insertions(+), 39 deletions(-) create mode 100644 .changelog/2572.txt create mode 100644 acceptance/tests/fixtures/bases/openshift/network-attachment.yaml create mode 100644 acceptance/tests/fixtures/cases/static-client-openshift-inject/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/static-client-openshift-inject/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/static-client-openshift-tproxy/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/static-client-openshift-tproxy/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/static-server-openshift/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/static-server-openshift/patch.yaml diff --git a/.changelog/2572.txt b/.changelog/2572.txt new file mode 100644 index 0000000000..4bc6c4ba50 --- /dev/null +++ b/.changelog/2572.txt @@ -0,0 +1,3 @@ +```release-note:improvement +helm: set container securityContexts to match the `restricted` Pod Security Standards policy to support running Consul in a namespace with restricted PSA enforcement enabled +``` diff --git a/acceptance/framework/config/config.go b/acceptance/framework/config/config.go index 74bb7daf6e..ee07df63fd 100644 --- a/acceptance/framework/config/config.go +++ b/acceptance/framework/config/config.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strconv" "strings" + "testing" "github.com/hashicorp/go-version" "gopkg.in/yaml.v2" @@ -73,7 +74,8 @@ type TestConfig struct { EnablePodSecurityPolicies bool - EnableCNI bool + EnableCNI bool + EnableRestrictedPSAEnforcement bool EnableTransparentProxy bool @@ -135,10 +137,22 @@ func (t *TestConfig) HelmValuesFromConfig() (map[string]string, error) { if t.EnableCNI { setIfNotEmpty(helmValues, "connectInject.cni.enabled", "true") + setIfNotEmpty(helmValues, "connectInject.cni.logLevel", "debug") // GKE is currently the only cloud provider that uses a different CNI bin dir. if t.UseGKE { setIfNotEmpty(helmValues, "connectInject.cni.cniBinDir", "/home/kubernetes/bin") } + if t.EnableOpenshift { + setIfNotEmpty(helmValues, "connectInject.cni.multus", "true") + setIfNotEmpty(helmValues, "connectInject.cni.cniBinDir", "/var/lib/cni/bin") + setIfNotEmpty(helmValues, "connectInject.cni.cniNetDir", "/etc/kubernetes/cni/net.d") + } + + if t.EnableRestrictedPSAEnforcement { + // The CNI requires privilege, so when restricted PSA enforcement is enabled on the Consul + // namespace it must be run in a different privileged namespace. + setIfNotEmpty(helmValues, "connectInject.cni.namespace", "kube-system") + } } setIfNotEmpty(helmValues, "connectInject.transparentProxy.defaultEnabled", strconv.FormatBool(t.EnableTransparentProxy)) @@ -220,6 +234,12 @@ func (t *TestConfig) entImage() (string, error) { return fmt.Sprintf("hashicorp/consul-enterprise:%s%s-ent", consulImageVersion, preRelease), nil } +func (c *TestConfig) SkipWhenOpenshiftAndCNI(t *testing.T) { + if c.EnableOpenshift && c.EnableCNI { + t.Skip("skipping because -enable-cni and -enable-openshift are set and this test doesn't deploy apps correctly") + } +} + // setIfNotEmpty sets key to val in map m if value is not empty. func setIfNotEmpty(m map[string]string, key, val string) { if val != "" { diff --git a/acceptance/framework/config/config_test.go b/acceptance/framework/config/config_test.go index 96f0f0e7eb..df981e26fa 100644 --- a/acceptance/framework/config/config_test.go +++ b/acceptance/framework/config/config_test.go @@ -116,6 +116,7 @@ func TestConfig_HelmValuesFromConfig(t *testing.T) { }, map[string]string{ "connectInject.cni.enabled": "true", + "connectInject.cni.logLevel": "debug", "connectInject.transparentProxy.defaultEnabled": "false", }, }, diff --git a/acceptance/framework/connhelper/connect_helper.go b/acceptance/framework/connhelper/connect_helper.go index c34f663563..2eb18c9dbb 100644 --- a/acceptance/framework/connhelper/connect_helper.go +++ b/acceptance/framework/connhelper/connect_helper.go @@ -6,9 +6,11 @@ package connhelper import ( "context" "strconv" + "strings" "testing" "time" + terratestK8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/config" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/environment" @@ -44,7 +46,12 @@ type ConnectHelper struct { // ReleaseName is the name of the Consul cluster. ReleaseName string + // Ctx is used to deploy Consul Ctx environment.TestContext + // UseAppNamespace is used top optionally deploy applications into a separate namespace. + // If unset, the namespace associated with Ctx is used. + UseAppNamespace bool + Cfg *config.TestConfig // consulCluster is the cluster to use for the test. @@ -82,6 +89,14 @@ func (c *ConnectHelper) Upgrade(t *testing.T) { c.consulCluster.Upgrade(t, c.helmValues()) } +func (c *ConnectHelper) KubectlOptsForApp(t *testing.T) *terratestK8s.KubectlOptions { + opts := c.Ctx.KubectlOptions(t) + if !c.UseAppNamespace { + return opts + } + return c.Ctx.KubectlOptionsForNamespace(opts.Namespace + "-apps") +} + // DeployClientAndServer deploys a client and server pod to the Kubernetes // cluster which will be used to test service mesh connectivity. If the Secure // flag is true, a pre-check is done to ensure that the ACL tokens for the test @@ -108,23 +123,46 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-server-inject") - if c.Cfg.EnableTransparentProxy { - k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + c.setupAppNamespace(t) + + opts := c.KubectlOptsForApp(t) + if c.Cfg.EnableCNI && c.Cfg.EnableOpenshift { + // On OpenShift with the CNI, we need to create a network attachment definition in the namespace + // where the applications are running, and the app deployment configs need to reference that network + // attachment definition. + + // TODO: A base fixture is the wrong place for these files + k8s.KubectlApply(t, opts, "../fixtures/bases/openshift/") + helpers.Cleanup(t, c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, func() { + k8s.KubectlDelete(t, opts, "../fixtures/bases/openshift/") + }) + + k8s.DeployKustomize(t, opts, c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-server-openshift") + if c.Cfg.EnableTransparentProxy { + k8s.DeployKustomize(t, opts, c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-openshift-tproxy") + } else { + k8s.DeployKustomize(t, opts, c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-openshift-inject") + } } else { - k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + if c.Cfg.EnableTransparentProxy { + k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-tproxy") + } else { + k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-client-inject") + } } - // Check that both static-server and static-client have been injected and // now have 2 containers. retry.RunWith( &retry.Timer{Timeout: 30 * time.Second, Wait: 100 * time.Millisecond}, t, func(r *retry.R) { for _, labelSelector := range []string{"app=static-server", "app=static-client"} { - podList, err := c.Ctx.KubernetesClient(t).CoreV1().Pods(c.Ctx.KubectlOptions(t).Namespace).List(context.Background(), metav1.ListOptions{ - LabelSelector: labelSelector, - FieldSelector: `status.phase=Running`, - }) + podList, err := c.Ctx.KubernetesClient(t).CoreV1(). + Pods(opts.Namespace). + List(context.Background(), metav1.ListOptions{ + LabelSelector: labelSelector, + FieldSelector: `status.phase=Running`, + }) require.NoError(r, err) require.Len(r, podList.Items, 1) require.Len(r, podList.Items[0].Spec.Containers, 2) @@ -132,16 +170,46 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { }) } +// setupAppNamespace creates a namespace where applications are deployed. This +// does nothing if UseAppNamespace is not set. The app namespace is relevant +// when testing with restricted PSA enforcement enabled. +func (c *ConnectHelper) setupAppNamespace(t *testing.T) { + if !c.UseAppNamespace { + return + } + opts := c.KubectlOptsForApp(t) + // If we are deploying apps in another namespace, create the namespace. + + _, err := k8s.RunKubectlAndGetOutputE(t, opts, "create", "ns", opts.Namespace) + if err != nil && strings.Contains(err.Error(), "AlreadyExists") { + return + } + require.NoError(t, err) + helpers.Cleanup(t, c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, func() { + k8s.RunKubectl(t, opts, "delete", "ns", opts.Namespace) + }) + + if c.Cfg.EnableRestrictedPSAEnforcement { + // Allow anything to run in the app namespace. + k8s.RunKubectl(t, opts, "label", "--overwrite", "ns", opts.Namespace, + "pod-security.kubernetes.io/enforce=privileged", + "pod-security.kubernetes.io/enforce-version=v1.24", + ) + } + +} + // CreateResolverRedirect creates a resolver that redirects to a static-server, a corresponding k8s service, // and intentions. This helper is primarly used to ensure that the virtual-ips are persisted to consul properly. func (c *ConnectHelper) CreateResolverRedirect(t *testing.T) { logger.Log(t, "creating resolver redirect") - options := c.Ctx.KubectlOptions(t) + opts := c.KubectlOptsForApp(t) + c.setupAppNamespace(t) kustomizeDir := "../fixtures/cases/resolver-redirect-virtualip" - k8s.KubectlApplyK(t, options, kustomizeDir) + k8s.KubectlApplyK(t, opts, kustomizeDir) helpers.Cleanup(t, c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, func() { - k8s.KubectlDeleteK(t, options, kustomizeDir) + k8s.KubectlDeleteK(t, opts, kustomizeDir) }) } @@ -149,10 +217,11 @@ func (c *ConnectHelper) CreateResolverRedirect(t *testing.T) { // server fails when no intentions are configured. func (c *ConnectHelper) TestConnectionFailureWithoutIntention(t *testing.T) { logger.Log(t, "checking that the connection is not successful because there's no intention") + opts := c.KubectlOptsForApp(t) if c.Cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionFailing(t, c.Ctx.KubectlOptions(t), StaticClientName, "http://static-server") + k8s.CheckStaticServerConnectionFailing(t, opts, StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionFailing(t, c.Ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, opts, StaticClientName, "http://localhost:1234") } } @@ -177,11 +246,12 @@ func (c *ConnectHelper) CreateIntention(t *testing.T) { // static-client pod once the intention is set. func (c *ConnectHelper) TestConnectionSuccess(t *testing.T) { logger.Log(t, "checking that connection is successful") + opts := c.KubectlOptsForApp(t) if c.Cfg.EnableTransparentProxy { // todo: add an assertion that the traffic is going through the proxy - k8s.CheckStaticServerConnectionSuccessful(t, c.Ctx.KubectlOptions(t), StaticClientName, "http://static-server") + k8s.CheckStaticServerConnectionSuccessful(t, opts, StaticClientName, "http://static-server") } else { - k8s.CheckStaticServerConnectionSuccessful(t, c.Ctx.KubectlOptions(t), StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, opts, StaticClientName, "http://localhost:1234") } } @@ -192,8 +262,10 @@ func (c *ConnectHelper) TestConnectionFailureWhenUnhealthy(t *testing.T) { // Test that kubernetes readiness status is synced to Consul. // Create a file called "unhealthy" at "/tmp/" so that the readiness probe // of the static-server pod fails. + opts := c.KubectlOptsForApp(t) + logger.Log(t, "testing k8s -> consul health checks sync by making the static-server unhealthy") - k8s.RunKubectl(t, c.Ctx.KubectlOptions(t), "exec", "deploy/"+StaticServerName, "--", "touch", "/tmp/unhealthy") + k8s.RunKubectl(t, opts, "exec", "deploy/"+StaticServerName, "--", "touch", "/tmp/unhealthy") // The readiness probe should take a moment to be reflected in Consul, // CheckStaticServerConnection will retry until Consul marks the service @@ -205,20 +277,20 @@ func (c *ConnectHelper) TestConnectionFailureWhenUnhealthy(t *testing.T) { // other tests. logger.Log(t, "checking that connection is unsuccessful") if c.Cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, c.Ctx.KubectlOptions(t), StaticClientName, false, []string{ + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, opts, StaticClientName, false, []string{ "curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", "curl: (7) Failed to connect to static-server port 80: Connection refused", }, "", "http://static-server") } else { - k8s.CheckStaticServerConnectionMultipleFailureMessages(t, c.Ctx.KubectlOptions(t), StaticClientName, false, []string{ + k8s.CheckStaticServerConnectionMultipleFailureMessages(t, opts, StaticClientName, false, []string{ "curl: (56) Recv failure: Connection reset by peer", "curl: (52) Empty reply from server", }, "", "http://localhost:1234") } // Return the static-server to a "healthy state". - k8s.RunKubectl(t, c.Ctx.KubectlOptions(t), "exec", "deploy/"+StaticServerName, "--", "rm", "/tmp/unhealthy") + k8s.RunKubectl(t, opts, "exec", "deploy/"+StaticServerName, "--", "rm", "/tmp/unhealthy") } // helmValues uses the Secure and AutoEncrypt fields to set values for the Helm diff --git a/acceptance/framework/consul/helm_cluster_test.go b/acceptance/framework/consul/helm_cluster_test.go index 9c44006d43..011ca23e0f 100644 --- a/acceptance/framework/consul/helm_cluster_test.go +++ b/acceptance/framework/consul/helm_cluster_test.go @@ -8,6 +8,7 @@ import ( "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/config" + "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/stretchr/testify/require" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" @@ -80,9 +81,14 @@ func (c *ctx) Name() string { func (c *ctx) KubectlOptions(_ *testing.T) *k8s.KubectlOptions { return &k8s.KubectlOptions{} } +func (c *ctx) KubectlOptionsForNamespace(ns string) *k8s.KubectlOptions { + return &k8s.KubectlOptions{} +} func (c *ctx) KubernetesClient(_ *testing.T) kubernetes.Interface { return fake.NewSimpleClientset() } func (c *ctx) ControllerRuntimeClient(_ *testing.T) client.Client { return runtimefake.NewClientBuilder().Build() } + +var _ environment.TestContext = (*ctx)(nil) diff --git a/acceptance/framework/environment/environment.go b/acceptance/framework/environment/environment.go index 9150f4ff03..7014a3c05f 100644 --- a/acceptance/framework/environment/environment.go +++ b/acceptance/framework/environment/environment.go @@ -35,6 +35,8 @@ type TestEnvironment interface { // for example, information about a specific Kubernetes cluster. type TestContext interface { KubectlOptions(t *testing.T) *k8s.KubectlOptions + // TODO: I don't love this. + KubectlOptionsForNamespace(ns string) *k8s.KubectlOptions KubernetesClient(t *testing.T) kubernetes.Interface ControllerRuntimeClient(t *testing.T) client.Client } @@ -138,6 +140,14 @@ func (k kubernetesContext) KubectlOptions(t *testing.T) *k8s.KubectlOptions { return k.options } +func (k kubernetesContext) KubectlOptionsForNamespace(ns string) *k8s.KubectlOptions { + return &k8s.KubectlOptions{ + ContextName: k.kubeContextName, + ConfigPath: k.pathToKubeConfig, + Namespace: ns, + } +} + // KubernetesClientFromOptions takes KubectlOptions and returns Kubernetes API client. func KubernetesClientFromOptions(t *testing.T, options *k8s.KubectlOptions) kubernetes.Interface { configPath, err := options.GetConfigPath(t) diff --git a/acceptance/framework/flags/flags.go b/acceptance/framework/flags/flags.go index b1ad7e4332..ce8e1ea726 100644 --- a/acceptance/framework/flags/flags.go +++ b/acceptance/framework/flags/flags.go @@ -27,7 +27,8 @@ type TestFlags struct { flagEnablePodSecurityPolicies bool - flagEnableCNI bool + flagEnableCNI bool + flagEnableRestrictedPSAEnforcement bool flagEnableTransparentProxy bool @@ -116,6 +117,13 @@ func (t *TestFlags) init() { flag.BoolVar(&t.flagEnableCNI, "enable-cni", false, "If true, the test suite will run tests with consul-cni plugin enabled. "+ "In general, this will only run against tests that are mesh related (connect, mesh-gateway, peering, etc") + flag.BoolVar(&t.flagEnableRestrictedPSAEnforcement, "enable-restricted-psa-enforcement", false, + "If true, this indicates that Consul is being run in a namespace with restricted PSA enforcement enabled. "+ + "The tests do not configure Consul's namespace with PSA enforcement enabled. This must configured before tests are run. "+ + "The CNI and test applications need more privilege than is allowed in a restricted namespace. "+ + "When set, the CNI will be deployed into the kube-system namespace, and in supported test cases, applications "+ + "are deployed, by default, into a namespace named '-apps' instead of being deployed into the "+ + "Consul namespace.") flag.BoolVar(&t.flagEnableTransparentProxy, "enable-transparent-proxy", false, "If true, the test suite will run tests with transparent proxy enabled. "+ @@ -176,6 +184,7 @@ func (t *TestFlags) Validate() error { if t.flagEnableEnterprise && t.flagEnterpriseLicense == "" { return errors.New("-enable-enterprise provided without setting env var CONSUL_ENT_LICENSE with consul license") } + return nil } @@ -200,7 +209,8 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { EnablePodSecurityPolicies: t.flagEnablePodSecurityPolicies, - EnableCNI: t.flagEnableCNI, + EnableCNI: t.flagEnableCNI, + EnableRestrictedPSAEnforcement: t.flagEnableRestrictedPSAEnforcement, EnableTransparentProxy: t.flagEnableTransparentProxy, diff --git a/acceptance/tests/connect/connect_external_servers_test.go b/acceptance/tests/connect/connect_external_servers_test.go index c421c1258e..46f9e14573 100644 --- a/acceptance/tests/connect/connect_external_servers_test.go +++ b/acceptance/tests/connect/connect_external_servers_test.go @@ -30,6 +30,8 @@ func TestConnectInject_ExternalServers(t *testing.T) { caseName := fmt.Sprintf("secure: %t", secure) t.Run(caseName, func(t *testing.T) { cfg := suite.Config() + cfg.SkipWhenOpenshiftAndCNI(t) + ctx := suite.Environment().DefaultContext(t) serverHelmValues := map[string]string{ diff --git a/acceptance/tests/connect/connect_inject_namespaces_test.go b/acceptance/tests/connect/connect_inject_namespaces_test.go index 6fb493ce17..7b7785a44f 100644 --- a/acceptance/tests/connect/connect_inject_namespaces_test.go +++ b/acceptance/tests/connect/connect_inject_namespaces_test.go @@ -34,6 +34,7 @@ func TestConnectInjectNamespaces(t *testing.T) { if !cfg.EnableEnterprise { t.Skipf("skipping this test because -enable-enterprise is not set") } + cfg.SkipWhenOpenshiftAndCNI(t) cases := []struct { name string @@ -246,6 +247,7 @@ func TestConnectInjectNamespaces_CleanupController(t *testing.T) { if !cfg.EnableEnterprise { t.Skipf("skipping this test because -enable-enterprise is not set") } + cfg.SkipWhenOpenshiftAndCNI(t) consulDestNS := "consul-dest" cases := []struct { diff --git a/acceptance/tests/connect/connect_inject_test.go b/acceptance/tests/connect/connect_inject_test.go index c239698d2a..7c7f17fc0a 100644 --- a/acceptance/tests/connect/connect_inject_test.go +++ b/acceptance/tests/connect/connect_inject_test.go @@ -38,11 +38,12 @@ func TestConnectInject(t *testing.T) { releaseName := helpers.RandomName() connHelper := connhelper.ConnectHelper{ - ClusterKind: consul.Helm, - Secure: c.secure, - ReleaseName: releaseName, - Ctx: ctx, - Cfg: cfg, + ClusterKind: consul.Helm, + Secure: c.secure, + ReleaseName: releaseName, + Ctx: ctx, + UseAppNamespace: cfg.EnableRestrictedPSAEnforcement, + Cfg: cfg, } connHelper.Setup(t) @@ -71,11 +72,12 @@ func TestConnectInject_VirtualIPFailover(t *testing.T) { releaseName := helpers.RandomName() connHelper := connhelper.ConnectHelper{ - ClusterKind: consul.Helm, - Secure: true, - ReleaseName: releaseName, - Ctx: ctx, - Cfg: cfg, + ClusterKind: consul.Helm, + Secure: true, + ReleaseName: releaseName, + Ctx: ctx, + UseAppNamespace: cfg.EnableRestrictedPSAEnforcement, + Cfg: cfg, } connHelper.Setup(t) @@ -84,7 +86,8 @@ func TestConnectInject_VirtualIPFailover(t *testing.T) { connHelper.CreateResolverRedirect(t) connHelper.DeployClientAndServer(t) - k8s.CheckStaticServerConnectionSuccessful(t, connHelper.Ctx.KubectlOptions(t), "static-client", "http://resolver-redirect") + opts := connHelper.KubectlOptsForApp(t) + k8s.CheckStaticServerConnectionSuccessful(t, opts, "static-client", "http://resolver-redirect") } // Test the endpoints controller cleans up force-killed pods. @@ -93,6 +96,9 @@ func TestConnectInject_CleanupKilledPods(t *testing.T) { name := fmt.Sprintf("secure: %t", secure) t.Run(name, func(t *testing.T) { cfg := suite.Config() + + cfg.SkipWhenOpenshiftAndCNI(t) + ctx := suite.Environment().DefaultContext(t) helmValues := map[string]string{ @@ -161,6 +167,8 @@ func TestConnectInject_MultiportServices(t *testing.T) { name := fmt.Sprintf("secure: %t", secure) t.Run(name, func(t *testing.T) { cfg := suite.Config() + cfg.SkipWhenOpenshiftAndCNI(t) + ctx := suite.Environment().DefaultContext(t) helmValues := map[string]string{ diff --git a/acceptance/tests/connect/connect_proxy_lifecycle_test.go b/acceptance/tests/connect/connect_proxy_lifecycle_test.go index 321c002a4c..39dd0b4ae7 100644 --- a/acceptance/tests/connect/connect_proxy_lifecycle_test.go +++ b/acceptance/tests/connect/connect_proxy_lifecycle_test.go @@ -34,6 +34,7 @@ const ( // Test the endpoints controller cleans up force-killed pods. func TestConnectInject_ProxyLifecycleShutdown(t *testing.T) { cfg := suite.Config() + cfg.SkipWhenOpenshiftAndCNI(t) for _, testCfg := range []LifecycleShutdownConfig{ {secure: false, helmValues: map[string]string{ diff --git a/acceptance/tests/connect/permissive_mtls_test.go b/acceptance/tests/connect/permissive_mtls_test.go index d07c44ae2f..929d56acfd 100644 --- a/acceptance/tests/connect/permissive_mtls_test.go +++ b/acceptance/tests/connect/permissive_mtls_test.go @@ -23,6 +23,7 @@ func TestConnectInject_PermissiveMTLS(t *testing.T) { if !cfg.EnableTransparentProxy { t.Skipf("skipping this because -enable-transparent-proxy is not set") } + cfg.SkipWhenOpenshiftAndCNI(t) ctx := suite.Environment().DefaultContext(t) diff --git a/acceptance/tests/fixtures/bases/openshift/network-attachment.yaml b/acceptance/tests/fixtures/bases/openshift/network-attachment.yaml new file mode 100644 index 0000000000..4b3f7948ee --- /dev/null +++ b/acceptance/tests/fixtures/bases/openshift/network-attachment.yaml @@ -0,0 +1,17 @@ +apiVersion: "k8s.cni.cncf.io/v1" +kind: NetworkAttachmentDefinition +metadata: + name: consul-cni +spec: + config: '{ + "cniVersion": "0.3.1", + "type": "consul-cni", + "cni_bin_dir": "/var/lib/cni/bin", + "cni_net_dir": "/etc/kubernetes/cni/net.d", + "kubeconfig": "ZZZ-consul-cni-kubeconfig", + "log_level": "debug", + "multus": true, + "name": "consul-cni", + "type": "consul-cni" + }' + diff --git a/acceptance/tests/fixtures/cases/static-client-openshift-inject/kustomization.yaml b/acceptance/tests/fixtures/cases/static-client-openshift-inject/kustomization.yaml new file mode 100644 index 0000000000..4d4a53b87f --- /dev/null +++ b/acceptance/tests/fixtures/cases/static-client-openshift-inject/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../bases/static-client + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/static-client-openshift-inject/patch.yaml b/acceptance/tests/fixtures/cases/static-client-openshift-inject/patch.yaml new file mode 100644 index 0000000000..8cc6d10411 --- /dev/null +++ b/acceptance/tests/fixtures/cases/static-client-openshift-inject/patch.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-client +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + "consul.hashicorp.com/connect-service-upstreams": "static-server:1234" + "k8s.v1.cni.cncf.io/networks": '[{ "name":"consul-cni" }]' diff --git a/acceptance/tests/fixtures/cases/static-client-openshift-tproxy/kustomization.yaml b/acceptance/tests/fixtures/cases/static-client-openshift-tproxy/kustomization.yaml new file mode 100644 index 0000000000..4d4a53b87f --- /dev/null +++ b/acceptance/tests/fixtures/cases/static-client-openshift-tproxy/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../bases/static-client + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/static-client-openshift-tproxy/patch.yaml b/acceptance/tests/fixtures/cases/static-client-openshift-tproxy/patch.yaml new file mode 100644 index 0000000000..3b9c91fcc0 --- /dev/null +++ b/acceptance/tests/fixtures/cases/static-client-openshift-tproxy/patch.yaml @@ -0,0 +1,18 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# When using the CNI on OpenShift, we need to specify the +# network attachment definition for the pods to use. This assumes +# that one named 'consul-cni' was created by the acceptance tests. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-client +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + "k8s.v1.cni.cncf.io/networks": '[{ "name":"consul-cni" }]' + diff --git a/acceptance/tests/fixtures/cases/static-server-openshift/kustomization.yaml b/acceptance/tests/fixtures/cases/static-server-openshift/kustomization.yaml new file mode 100644 index 0000000000..bc50c78adf --- /dev/null +++ b/acceptance/tests/fixtures/cases/static-server-openshift/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../bases/static-server + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/static-server-openshift/patch.yaml b/acceptance/tests/fixtures/cases/static-server-openshift/patch.yaml new file mode 100644 index 0000000000..8e2ed857f3 --- /dev/null +++ b/acceptance/tests/fixtures/cases/static-server-openshift/patch.yaml @@ -0,0 +1,42 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-server +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + "k8s.v1.cni.cncf.io/networks": '[{ "name":"consul-cni" }]' + spec: + containers: + - name: static-server + image: docker.mirror.hashicorp.services/kschoche/http-echo:latest + args: + - -text="hello world" + - -listen=:8080 + ports: + - containerPort: 8080 + name: http + livenessProbe: + httpGet: + port: 8080 + initialDelaySeconds: 1 + failureThreshold: 1 + periodSeconds: 1 + startupProbe: + httpGet: + port: 8080 + initialDelaySeconds: 1 + failureThreshold: 30 + periodSeconds: 1 + readinessProbe: + exec: + command: ['sh', '-c', 'test ! -f /tmp/unhealthy'] + initialDelaySeconds: 1 + failureThreshold: 1 + periodSeconds: 1 + serviceAccountName: static-server diff --git a/charts/consul/templates/_helpers.tpl b/charts/consul/templates/_helpers.tpl index 1b866888c0..18f57b188c 100644 --- a/charts/consul/templates/_helpers.tpl +++ b/charts/consul/templates/_helpers.tpl @@ -15,6 +15,29 @@ as well as the global.name setting. {{- end -}} {{- end -}} +{{- define "consul.restrictedSecurityContext" -}} +{{- if not .Values.global.enablePodSecurityPolicies -}} +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault +{{- if not .Values.global.openshift.enabled -}} +{{/* +We must set runAsUser or else the root user will be used in some cases and +containers will fail to start due to runAsNonRoot above (e.g. +tls-init-cleanup). On OpenShift, runAsUser is automatically. We pick user 100 +because it is a non-root user id that exists in the consul, consul-dataplane, +and consul-k8s-control-plane images. +*/}} + runAsUser: 100 +{{- end -}} +{{- end -}} +{{- end -}} + {{- define "consul.vaultSecretTemplate" -}} | {{ "{{" }}- with secret "{{ .secretName }}" -{{ "}}" }} @@ -422,4 +445,4 @@ Usage: {{ template "consul.validateTelemetryCollectorCloud" . }} {{- if or (and .Values.telemetryCollector.cloud.clientSecret.secretName .Values.telemetryCollector.cloud.clientSecret.secretKey .Values.telemetryCollector.cloud.clientId.secretName .Values.telemetryCollector.cloud.clientId.secretKey (not .Values.global.cloud.resourceId.secretKey)) }} {{fail "When telemetryCollector has clientId and clientSecret .global.cloud.resourceId.secretKey must be set"}} {{- end }} -{{- end -}} \ No newline at end of file +{{- end -}} diff --git a/charts/consul/templates/connect-inject-deployment.yaml b/charts/consul/templates/connect-inject-deployment.yaml index 14c3961b4e..e726c9ecc9 100644 --- a/charts/consul/templates/connect-inject-deployment.yaml +++ b/charts/consul/templates/connect-inject-deployment.yaml @@ -94,6 +94,7 @@ spec: - containerPort: 8080 name: webhook-server protocol: TCP + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/gateway-cleanup-job.yaml b/charts/consul/templates/gateway-cleanup-job.yaml index 8731aaed81..a987c3b591 100644 --- a/charts/consul/templates/gateway-cleanup-job.yaml +++ b/charts/consul/templates/gateway-cleanup-job.yaml @@ -40,6 +40,7 @@ spec: containers: - name: gateway-cleanup image: {{ .Values.global.imageK8S }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/gateway-resources-job.yaml b/charts/consul/templates/gateway-resources-job.yaml index 5fcd96cad3..3a29f75e66 100644 --- a/charts/consul/templates/gateway-resources-job.yaml +++ b/charts/consul/templates/gateway-resources-job.yaml @@ -40,6 +40,7 @@ spec: containers: - name: gateway-resources image: {{ .Values.global.imageK8S }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/gossip-encryption-autogenerate-job.yaml b/charts/consul/templates/gossip-encryption-autogenerate-job.yaml index 9d296478a1..240bfe3f9c 100644 --- a/charts/consul/templates/gossip-encryption-autogenerate-job.yaml +++ b/charts/consul/templates/gossip-encryption-autogenerate-job.yaml @@ -48,6 +48,7 @@ spec: containers: - name: gossip-encryption-autogen image: "{{ .Values.global.imageK8S }}" + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} command: - "/bin/sh" - "-ec" diff --git a/charts/consul/templates/server-acl-init-cleanup-job.yaml b/charts/consul/templates/server-acl-init-cleanup-job.yaml index 4d0aa8f05d..c9f6763bd8 100644 --- a/charts/consul/templates/server-acl-init-cleanup-job.yaml +++ b/charts/consul/templates/server-acl-init-cleanup-job.yaml @@ -60,6 +60,9 @@ spec: containers: - name: server-acl-init-cleanup image: {{ .Values.global.imageK8S }} + {{- if not .Values.server.containerSecurityContext.aclInit }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + {{- end }} command: - consul-k8s-control-plane args: diff --git a/charts/consul/templates/server-acl-init-job.yaml b/charts/consul/templates/server-acl-init-job.yaml index 6625e23b38..c3d4a710e8 100644 --- a/charts/consul/templates/server-acl-init-job.yaml +++ b/charts/consul/templates/server-acl-init-job.yaml @@ -129,6 +129,9 @@ spec: containers: - name: server-acl-init-job image: {{ .Values.global.imageK8S }} + {{- if not .Values.server.containerSecurityContext.aclInit }} + {{- include "consul.restrictedSecurityContext" . | nindent 8 }} + {{- end }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 9efbcb8085..2ad04f0755 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -238,6 +238,7 @@ spec: volumeMounts: - name: extra-config mountPath: /consul/extra-config + {{- include "consul.restrictedSecurityContext" . | nindent 8 }} containers: - name: consul image: "{{ default .Values.global.image .Values.server.image }}" @@ -527,9 +528,11 @@ spec: {{- toYaml .Values.server.resources | nindent 12 }} {{- end }} {{- end }} - {{- if not .Values.global.openshift.enabled }} + {{- if .Values.server.containerSecurityContext.server }} securityContext: {{- toYaml .Values.server.containerSecurityContext.server | nindent 12 }} + {{- else }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} {{- end }} {{- if .Values.server.extraContainers }} {{ toYaml .Values.server.extraContainers | nindent 8 }} diff --git a/charts/consul/templates/tls-init-cleanup-job.yaml b/charts/consul/templates/tls-init-cleanup-job.yaml index 69b5a30849..2254a38ed2 100644 --- a/charts/consul/templates/tls-init-cleanup-job.yaml +++ b/charts/consul/templates/tls-init-cleanup-job.yaml @@ -48,6 +48,9 @@ spec: containers: - name: tls-init-cleanup image: "{{ .Values.global.image }}" + {{- if not .Values.server.containerSecurityContext.tlsInit }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + {{- end }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/tls-init-job.yaml b/charts/consul/templates/tls-init-job.yaml index 5839f07dbf..12d3acbad8 100644 --- a/charts/consul/templates/tls-init-job.yaml +++ b/charts/consul/templates/tls-init-job.yaml @@ -63,6 +63,9 @@ spec: containers: - name: tls-init image: "{{ .Values.global.imageK8S }}" + {{- if not .Values.server.containerSecurityContext.tlsInit }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} + {{- end }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/webhook-cert-manager-deployment.yaml b/charts/consul/templates/webhook-cert-manager-deployment.yaml index dd93c039d2..7ba25b330c 100644 --- a/charts/consul/templates/webhook-cert-manager-deployment.yaml +++ b/charts/consul/templates/webhook-cert-manager-deployment.yaml @@ -51,6 +51,7 @@ spec: -deployment-namespace={{ .Release.Namespace }} image: {{ .Values.global.imageK8S }} name: webhook-cert-manager + {{- include "consul.restrictedSecurityContext" . | nindent 8 }} resources: limits: cpu: 100m diff --git a/charts/consul/test/unit/server-statefulset.bats b/charts/consul/test/unit/server-statefulset.bats index 108fd9bbf8..a60884d20c 100755 --- a/charts/consul/test/unit/server-statefulset.bats +++ b/charts/consul/test/unit/server-statefulset.bats @@ -829,9 +829,9 @@ load _helpers } #-------------------------------------------------------------------- -# global.openshift.enabled & client.containerSecurityContext +# global.openshift.enabled && server.containerSecurityContext -@test "server/StatefulSet: container level securityContexts are not set when global.openshift.enabled=true" { +@test "server/StatefulSet: Can set container level securityContexts when global.openshift.enabled=true" { cd `chart_dir` local manifest=$(helm template \ -s templates/server-statefulset.yaml \ @@ -839,8 +839,72 @@ load _helpers --set 'server.containerSecurityContext.server.privileged=false' \ . | tee /dev/stderr) + local actual=$(echo "$manifest" | yq -r '.spec.template.spec.containers | map(select(.name == "consul")) | .[0].securityContext.privileged') + [ "${actual}" = "false" ] +} + +#-------------------------------------------------------------------- +# global.openshift.enabled + +@test "server/StatefulSet: restricted container securityContexts are set when global.openshift.enabled=true" { + cd `chart_dir` + local manifest=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.openshift.enabled=true' \ + . | tee /dev/stderr) + + local expected=$(echo '{ + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": ["ALL"] + }, + "runAsNonRoot": true, + "seccompProfile": { + "type": "RuntimeDefault" + } + }') + + # Check consul container local actual=$(echo "$manifest" | yq -r '.spec.template.spec.containers | map(select(.name == "consul")) | .[0].securityContext') - [ "${actual}" = "null" ] + local equal=$(jq -n --argjson a "$actual" --argjson b "$expected" '$a == $b') + [ "$equal" == "true" ] + + # Check locality-init container + local actual=$(echo "$manifest" | yq -r '.spec.template.spec.initContainers | map(select(.name == "locality-init")) | .[0].securityContext') + local equal=$(jq -n --argjson a "$actual" --argjson b "$expected" '$a == $b') + [ "$equal" == "true" ] +} + +#-------------------------------------------------------------------- +# global.openshift.enabled = false + +@test "server/StatefulSet: restricted container securityContexts are set by default" { + cd `chart_dir` + local manifest=$(helm template \ + -s templates/server-statefulset.yaml \ + . | tee /dev/stderr) + + local expected=$(echo '{ + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": ["ALL"] + }, + "runAsNonRoot": true, + "seccompProfile": { + "type": "RuntimeDefault" + }, + "runAsUser": 100 + }') + + # Check consul container + local actual=$(echo "$manifest" | yq -r '.spec.template.spec.containers | map(select(.name == "consul")) | .[0].securityContext') + local equal=$(jq -n --argjson a "$actual" --argjson b "$expected" '$a == $b') + [ "$equal" == "true" ] + + # Check locality-init container + local actual=$(echo "$manifest" | yq -r '.spec.template.spec.initContainers | map(select(.name == "locality-init")) | .[0].securityContext') + local equal=$(jq -n --argjson a "$actual" --argjson b "$expected" '$a == $b') + [ "$equal" == "true" ] } #-------------------------------------------------------------------- From a924e88554a2c2a8ce1110734c15660e7688a451 Mon Sep 17 00:00:00 2001 From: skpratt Date: Mon, 24 Jul 2023 12:18:27 -0500 Subject: [PATCH 087/120] change fips delimiter to + (#2480) (#2591) --- .github/workflows/build.yml | 30 +++++++++++++++--------------- cli/version/version.go | 2 +- control-plane/version/version.go | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12904b3070..f79369b440 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -79,9 +79,9 @@ jobs: - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402", pkg_suffix: "-fips" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402", pkg_suffix: "-fips" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: "+fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: "+fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "cli", pkg_name: "consul-k8s", "bin_name": "consul-k8s.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: "+fips1402" } # control-plane - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "freebsd", goarch: "386", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } @@ -96,9 +96,9 @@ jobs: - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402", pkg_suffix: "-fips" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402", pkg_suffix: "-fips" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: "+fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: "+fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane", pkg_name: "consul-k8s-control-plane", "bin_name": "consul-k8s-control-plane.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: "+fips1402" } # consul-cni - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "freebsd", goarch: "386", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } @@ -112,9 +112,9 @@ jobs: - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni.exe" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "darwin", goarch: "arm64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: ".fips1402", pkg_suffix: "-fips" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: ".fips1402", pkg_suffix: "-fips" } - - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: ".fips1402" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto", fips: "+fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "linux", goarch: "arm64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=boringcrypto CC=aarch64-linux-gnu-gcc", fips: "+fips1402", pkg_suffix: "-fips" } + - {go: "${{ needs.get-go-version.outputs.go-version }}", goos: "windows", goarch: "amd64", component: "control-plane/cni", pkg_name: "consul-cni", "bin_name": "consul-cni.exe", gotags: "fips", env: "CGO_ENABLED=1 GOEXPERIMENT=cngcrypto", fips: "+fips1402" } fail-fast: true @@ -129,7 +129,7 @@ jobs: go-version: ${{ matrix.go }} - name: Replace Go for Windows FIPS with Microsoft Go - if: ${{ matrix.fips == '.fips1402' && matrix.goos == 'windows' }} + if: ${{ matrix.fips == '+fips1402' && matrix.goos == 'windows' }} run: | # Uninstall standard Go and use microsoft/go instead rm -rf /home/runner/actions-runner/_work/_tool/go @@ -143,7 +143,7 @@ jobs: fi - name: Install cross-compiler for FIPS on arm - if: ${{ matrix.fips == '.fips1402' && matrix.goarch == 'arm64' }} + if: ${{ matrix.fips == '+fips1402' && matrix.goarch == 'arm64' }} run: | sudo apt-get update --allow-releaseinfo-change-suite --allow-releaseinfo-change-version && sudo apt-get install -y gcc-aarch64-linux-gnu @@ -252,8 +252,8 @@ jobs: - { goos: "linux", goarch: "arm64" } - { goos: "linux", goarch: "386" } - { goos: "linux", goarch: "amd64" } - - { goos: "linux", goarch: "amd64", fips: ".fips1402" } - - { goos: "linux", goarch: "arm64", fips: ".fips1402" } + - { goos: "linux", goarch: "amd64", fips: "+fips1402" } + - { goos: "linux", goarch: "arm64", fips: "+fips1402" } env: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} @@ -323,7 +323,7 @@ jobs: matrix: include: - { arch: "amd64" } - - { arch: "amd64", fips: ".fips1402" } + - { arch: "amd64", fips: "+fips1402" } env: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} @@ -386,7 +386,7 @@ jobs: strategy: matrix: arch: [ "amd64" ] - fips: [ ".fips1402", "" ] + fips: [ "+fips1402", "" ] env: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} diff --git a/cli/version/version.go b/cli/version/version.go index 9cde4a2d66..952cd9ca81 100644 --- a/cli/version/version.go +++ b/cli/version/version.go @@ -40,7 +40,7 @@ func GetHumanVersion() string { } if IsFIPS() { - version += ".fips1402" + version += "+fips1402" } if release != "" { diff --git a/control-plane/version/version.go b/control-plane/version/version.go index 9cde4a2d66..952cd9ca81 100644 --- a/control-plane/version/version.go +++ b/control-plane/version/version.go @@ -40,7 +40,7 @@ func GetHumanVersion() string { } if IsFIPS() { - version += ".fips1402" + version += "+fips1402" } if release != "" { From 5b57e6340dff44157cb7a984ac7220e47849dfb9 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Mon, 24 Jul 2023 16:59:34 -0400 Subject: [PATCH 088/120] [NET-4865] security: Upgrade Go and net/http CVE-2023-29406 (#2642) security: Upgrade Go and net/http Upgrade to Go 1.20.6 and `net/http` 1.12.0 to resolve CVE-2023-29406. --- .changelog/2642.txt | 4 ++++ .go-version | 2 +- acceptance/go.mod | 10 +++++----- acceptance/go.sum | 20 ++++++++++---------- cli/go.mod | 10 +++++----- cli/go.sum | 19 ++++++++++--------- control-plane/go.mod | 10 +++++----- control-plane/go.sum | 20 ++++++++++---------- 8 files changed, 50 insertions(+), 45 deletions(-) create mode 100644 .changelog/2642.txt diff --git a/.changelog/2642.txt b/.changelog/2642.txt new file mode 100644 index 0000000000..5278ed705c --- /dev/null +++ b/.changelog/2642.txt @@ -0,0 +1,4 @@ +```release-note:security +Upgrade to use Go 1.20.6 and `x/net/http` 0.12.0. +This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). +``` diff --git a/.go-version b/.go-version index 0bd54efd31..e63679c766 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.20.4 +1.20.6 diff --git a/acceptance/go.mod b/acceptance/go.mod index 382d9f8225..b19015eda4 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -119,14 +119,14 @@ require ( go.opentelemetry.io/otel v1.11.1 // indirect go.opentelemetry.io/otel/trace v1.11.1 // indirect go.uber.org/atomic v1.9.0 // indirect - golang.org/x/crypto v0.1.0 // indirect + golang.org/x/crypto v0.11.0 // indirect golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/net v0.12.0 // indirect golang.org/x/oauth2 v0.6.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.7.0 // indirect gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index 53b9400c42..43a557f32b 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -800,8 +800,8 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -887,8 +887,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -984,13 +984,13 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1001,8 +1001,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/cli/go.mod b/cli/go.mod index cdee871f38..5744e9dad0 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -17,7 +17,7 @@ require ( github.com/olekukonko/tablewriter v0.0.5 github.com/posener/complete v1.2.3 github.com/stretchr/testify v1.8.3 - golang.org/x/text v0.9.0 + golang.org/x/text v0.11.0 helm.sh/helm/v3 v3.9.4 k8s.io/api v0.25.0 k8s.io/apiextensions-apiserver v0.25.0 @@ -166,13 +166,13 @@ require ( github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect go.mongodb.org/mongo-driver v1.11.1 // indirect go.starlark.net v0.0.0-20230128213706-3f75dec8e403 // indirect - golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect + golang.org/x/crypto v0.11.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/net v0.12.0 // indirect golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect diff --git a/cli/go.sum b/cli/go.sum index 41b515d2e4..7861cb73d3 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -873,8 +873,9 @@ golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -962,8 +963,8 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1075,14 +1076,14 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1092,8 +1093,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/control-plane/go.mod b/control-plane/go.mod index 71396e2fd1..9d184840cb 100644 --- a/control-plane/go.mod +++ b/control-plane/go.mod @@ -29,7 +29,7 @@ require ( github.com/stretchr/testify v1.8.3 go.uber.org/zap v1.24.0 golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 - golang.org/x/text v0.9.0 + golang.org/x/text v0.11.0 golang.org/x/time v0.3.0 gomodules.xyz/jsonpatch/v2 v2.3.0 gopkg.in/yaml.v2 v2.4.0 @@ -143,13 +143,13 @@ require ( go.opencensus.io v0.22.4 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect - golang.org/x/crypto v0.1.0 // indirect + golang.org/x/crypto v0.11.0 // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.10.0 // indirect + golang.org/x/net v0.12.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.8.0 // indirect - golang.org/x/term v0.8.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect golang.org/x/tools v0.7.0 // indirect google.golang.org/api v0.30.0 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/control-plane/go.sum b/control-plane/go.sum index 2f7cbde2fc..fa88dab62a 100644 --- a/control-plane/go.sum +++ b/control-plane/go.sum @@ -574,8 +574,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -655,8 +655,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -743,13 +743,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -759,8 +759,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 6b26d91a8a2c1b5f9e4716779cf3b13aa35bfdd6 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Tue, 25 Jul 2023 15:18:51 -0400 Subject: [PATCH 089/120] Consul client always logs into the local datacenter (#2652) The consul client always logs into the local datacenter --- .changelog/2652.txt | 3 +++ charts/consul/templates/client-daemonset.yaml | 4 ---- charts/consul/test/unit/client-daemonset.bats | 23 ------------------- 3 files changed, 3 insertions(+), 27 deletions(-) create mode 100644 .changelog/2652.txt diff --git a/.changelog/2652.txt b/.changelog/2652.txt new file mode 100644 index 0000000000..efa290c0e7 --- /dev/null +++ b/.changelog/2652.txt @@ -0,0 +1,3 @@ +```release-note:bug +helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. +``` \ No newline at end of file diff --git a/charts/consul/templates/client-daemonset.yaml b/charts/consul/templates/client-daemonset.yaml index 09a70b394e..345c5c731e 100644 --- a/charts/consul/templates/client-daemonset.yaml +++ b/charts/consul/templates/client-daemonset.yaml @@ -510,11 +510,7 @@ spec: value: "component=client,pod=$(NAMESPACE)/$(POD_NAME)" {{- end }} - name: CONSUL_LOGIN_DATACENTER - {{- if and .Values.global.federation.enabled .Values.global.federation.primaryDatacenter }} - value: {{ .Values.global.federation.primaryDatacenter }} - {{- else }} value: {{ .Values.global.datacenter }} - {{- end}} command: - "/bin/sh" - "-ec" diff --git a/charts/consul/test/unit/client-daemonset.bats b/charts/consul/test/unit/client-daemonset.bats index 4c38207635..6e7a030cb1 100755 --- a/charts/consul/test/unit/client-daemonset.bats +++ b/charts/consul/test/unit/client-daemonset.bats @@ -2127,29 +2127,6 @@ rollingUpdate: [[ "$output" =~ "If global.federation.enabled is true, global.adminPartitions.enabled must be false because they are mutually exclusive" ]] } -@test "client/DaemonSet: consul login datacenter is set to primary when when federation enabled in non-primary datacenter" { - cd `chart_dir` - local object=$(helm template \ - -s templates/client-daemonset.yaml \ - --set 'client.enabled=true' \ - --set 'meshGateway.enabled=true' \ - --set 'global.acls.manageSystemACLs=true' \ - --set 'global.datacenter=dc1' \ - --set 'global.federation.enabled=true' \ - --set 'global.federation.primaryDatacenter=dc2' \ - --set 'global.tls.enabled=true' \ - . | tee /dev/stderr | - yq '.spec.template.spec.initContainers[] | select(.name == "client-acl-init")' | tee /dev/stderr) - - local actual=$(echo $object | - yq '[.env[11].name] | any(contains("CONSUL_LOGIN_DATACENTER"))' | tee /dev/stderr) - [ "${actual}" = "true" ] - - local actual=$(echo $object | - yq '[.env[11].value] | any(contains("dc2"))' | tee /dev/stderr) - [ "${actual}" = "true" ] -} - #-------------------------------------------------------------------- # extraContainers From 89a1c6ddfebe00050d7a99a4525aa4da3e6a72ab Mon Sep 17 00:00:00 2001 From: Mark Campbell-Vincent Date: Tue, 25 Jul 2023 16:54:20 -0400 Subject: [PATCH 090/120] Add support for requestTimeout in Service Resolver spec (#2641) * Add support for requestTimeout in Service Resolver spec * preserve serviceresolvers.yaml Preserving yaml from main, only adding requesttimeout property. * update generated.deepcopy.go * Use latest controller-gen to generate CRDs --------- Co-authored-by: Ashwin Venkatesh --- .../crd-controlplanerequestlimits.yaml | 5 +- .../templates/crd-exportedservices.yaml | 5 +- .../templates/crd-gatewayclassconfigs.yaml | 5 +- .../consul/templates/crd-gatewayclasses.yaml | 3 +- charts/consul/templates/crd-gateways.yaml | 3 +- charts/consul/templates/crd-grpcroutes.yaml | 3 +- charts/consul/templates/crd-httproutes.yaml | 3 +- .../consul/templates/crd-ingressgateways.yaml | 5 +- charts/consul/templates/crd-jwtproviders.yaml | 5 +- charts/consul/templates/crd-meshes.yaml | 5 +- charts/consul/templates/crd-meshservices.yaml | 5 +- .../templates/crd-peeringacceptors.yaml | 5 +- .../consul/templates/crd-peeringdialers.yaml | 5 +- .../consul/templates/crd-proxydefaults.yaml | 5 +- .../consul/templates/crd-referencegrants.yaml | 3 + .../consul/templates/crd-samenessgroups.yaml | 5 +- .../consul/templates/crd-servicedefaults.yaml | 5 +- .../templates/crd-serviceintentions.yaml | 5 +- .../templates/crd-serviceresolvers.yaml | 18 +- .../consul/templates/crd-servicerouters.yaml | 5 +- .../templates/crd-servicesplitters.yaml | 5 +- charts/consul/templates/crd-tcproutes.yaml | 3 + .../templates/crd-terminatinggateways.yaml | 5 +- charts/consul/templates/crd-tlsroutes.yaml | 3 + charts/consul/templates/crd-udproutes.yaml | 3 + .../api/v1alpha1/serviceresolver_types.go | 4 + .../v1alpha1/serviceresolver_types_test.go | 4 + .../api/v1alpha1/zz_generated.deepcopy.go | 158 ++++++++++++++++-- ...shicorp.com_controlplanerequestlimits.yaml | 3 +- ...consul.hashicorp.com_exportedservices.yaml | 3 +- ...sul.hashicorp.com_gatewayclassconfigs.yaml | 3 +- .../consul.hashicorp.com_ingressgateways.yaml | 3 +- .../consul.hashicorp.com_jwtproviders.yaml | 3 +- .../bases/consul.hashicorp.com_meshes.yaml | 3 +- .../consul.hashicorp.com_meshservices.yaml | 3 +- ...consul.hashicorp.com_peeringacceptors.yaml | 3 +- .../consul.hashicorp.com_peeringdialers.yaml | 3 +- .../consul.hashicorp.com_proxydefaults.yaml | 3 +- .../consul.hashicorp.com_samenessgroups.yaml | 3 +- .../consul.hashicorp.com_servicedefaults.yaml | 3 +- ...onsul.hashicorp.com_serviceintentions.yaml | 3 +- ...consul.hashicorp.com_serviceresolvers.yaml | 16 +- .../consul.hashicorp.com_servicerouters.yaml | 3 +- ...consul.hashicorp.com_servicesplitters.yaml | 3 +- ...sul.hashicorp.com_terminatinggateways.yaml | 3 +- control-plane/config/rbac/role.yaml | 4 - control-plane/config/webhook/manifests.yaml | 4 - 47 files changed, 241 insertions(+), 119 deletions(-) diff --git a/charts/consul/templates/crd-controlplanerequestlimits.yaml b/charts/consul/templates/crd-controlplanerequestlimits.yaml index bd1d6118b9..67ff258eb8 100644 --- a/charts/consul/templates/crd-controlplanerequestlimits.yaml +++ b/charts/consul/templates/crd-controlplanerequestlimits.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: controlplanerequestlimits.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: ControlPlaneRequestLimit diff --git a/charts/consul/templates/crd-exportedservices.yaml b/charts/consul/templates/crd-exportedservices.yaml index 7ffddf7537..8581ac4e88 100644 --- a/charts/consul/templates/crd-exportedservices.yaml +++ b/charts/consul/templates/crd-exportedservices.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: exportedservices.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: ExportedServices diff --git a/charts/consul/templates/crd-gatewayclassconfigs.yaml b/charts/consul/templates/crd-gatewayclassconfigs.yaml index 65d425edc4..7060757b23 100644 --- a/charts/consul/templates/crd-gatewayclassconfigs.yaml +++ b/charts/consul/templates/crd-gatewayclassconfigs.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: gatewayclassconfigs.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: GatewayClassConfig diff --git a/charts/consul/templates/crd-gatewayclasses.yaml b/charts/consul/templates/crd-gatewayclasses.yaml index 93435b7fce..8f381a7065 100644 --- a/charts/consul/templates/crd-gatewayclasses.yaml +++ b/charts/consul/templates/crd-gatewayclasses.yaml @@ -1,3 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6,7 +8,6 @@ metadata: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 gateway.networking.k8s.io/bundle-version: v0.6.2 gateway.networking.k8s.io/channel: experimental - creationTimestamp: null labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/charts/consul/templates/crd-gateways.yaml b/charts/consul/templates/crd-gateways.yaml index 41df34942a..d9c381b1de 100644 --- a/charts/consul/templates/crd-gateways.yaml +++ b/charts/consul/templates/crd-gateways.yaml @@ -1,3 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6,7 +8,6 @@ metadata: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 gateway.networking.k8s.io/bundle-version: v0.6.2 gateway.networking.k8s.io/channel: experimental - creationTimestamp: null labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/charts/consul/templates/crd-grpcroutes.yaml b/charts/consul/templates/crd-grpcroutes.yaml index 739ed2c659..cc126d73c3 100644 --- a/charts/consul/templates/crd-grpcroutes.yaml +++ b/charts/consul/templates/crd-grpcroutes.yaml @@ -1,3 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6,7 +8,6 @@ metadata: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 gateway.networking.k8s.io/bundle-version: v0.6.2 gateway.networking.k8s.io/channel: experimental - creationTimestamp: null labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/charts/consul/templates/crd-httproutes.yaml b/charts/consul/templates/crd-httproutes.yaml index bba3672d16..5f45528567 100644 --- a/charts/consul/templates/crd-httproutes.yaml +++ b/charts/consul/templates/crd-httproutes.yaml @@ -1,3 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition @@ -6,7 +8,6 @@ metadata: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 gateway.networking.k8s.io/bundle-version: v0.6.2 gateway.networking.k8s.io/channel: experimental - creationTimestamp: null labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} diff --git a/charts/consul/templates/crd-ingressgateways.yaml b/charts/consul/templates/crd-ingressgateways.yaml index ef33890461..eff7ef61a9 100644 --- a/charts/consul/templates/crd-ingressgateways.yaml +++ b/charts/consul/templates/crd-ingressgateways.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: ingressgateways.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: IngressGateway diff --git a/charts/consul/templates/crd-jwtproviders.yaml b/charts/consul/templates/crd-jwtproviders.yaml index c7d20883e8..fa87f37489 100644 --- a/charts/consul/templates/crd-jwtproviders.yaml +++ b/charts/consul/templates/crd-jwtproviders.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: jwtproviders.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: JWTProvider diff --git a/charts/consul/templates/crd-meshes.yaml b/charts/consul/templates/crd-meshes.yaml index cdc11b6ed9..f2549b5111 100644 --- a/charts/consul/templates/crd-meshes.yaml +++ b/charts/consul/templates/crd-meshes.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: meshes.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: Mesh diff --git a/charts/consul/templates/crd-meshservices.yaml b/charts/consul/templates/crd-meshservices.yaml index 859c8683ee..aa808113a2 100644 --- a/charts/consul/templates/crd-meshservices.yaml +++ b/charts/consul/templates/crd-meshservices.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: meshservices.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: MeshService diff --git a/charts/consul/templates/crd-peeringacceptors.yaml b/charts/consul/templates/crd-peeringacceptors.yaml index 3822f3bdfe..40f7f1d4d6 100644 --- a/charts/consul/templates/crd-peeringacceptors.yaml +++ b/charts/consul/templates/crd-peeringacceptors.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: peeringacceptors.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: PeeringAcceptor diff --git a/charts/consul/templates/crd-peeringdialers.yaml b/charts/consul/templates/crd-peeringdialers.yaml index 405361c486..bfe4778d0c 100644 --- a/charts/consul/templates/crd-peeringdialers.yaml +++ b/charts/consul/templates/crd-peeringdialers.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: peeringdialers.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: PeeringDialer diff --git a/charts/consul/templates/crd-proxydefaults.yaml b/charts/consul/templates/crd-proxydefaults.yaml index 30dd25f674..a224effc12 100644 --- a/charts/consul/templates/crd-proxydefaults.yaml +++ b/charts/consul/templates/crd-proxydefaults.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: proxydefaults.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: ProxyDefaults diff --git a/charts/consul/templates/crd-referencegrants.yaml b/charts/consul/templates/crd-referencegrants.yaml index db9cf12027..d50211291d 100644 --- a/charts/consul/templates/crd-referencegrants.yaml +++ b/charts/consul/templates/crd-referencegrants.yaml @@ -1,4 +1,7 @@ {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-samenessgroups.yaml b/charts/consul/templates/crd-samenessgroups.yaml index c1d1c85a8e..7cc3b71ae1 100644 --- a/charts/consul/templates/crd-samenessgroups.yaml +++ b/charts/consul/templates/crd-samenessgroups.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: samenessgroups.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: SamenessGroup diff --git a/charts/consul/templates/crd-servicedefaults.yaml b/charts/consul/templates/crd-servicedefaults.yaml index c926ece62a..e295732bfa 100644 --- a/charts/consul/templates/crd-servicedefaults.yaml +++ b/charts/consul/templates/crd-servicedefaults.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: servicedefaults.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: ServiceDefaults diff --git a/charts/consul/templates/crd-serviceintentions.yaml b/charts/consul/templates/crd-serviceintentions.yaml index 335d2eff7a..5f849f65ba 100644 --- a/charts/consul/templates/crd-serviceintentions.yaml +++ b/charts/consul/templates/crd-serviceintentions.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: serviceintentions.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: ServiceIntentions diff --git a/charts/consul/templates/crd-serviceresolvers.yaml b/charts/consul/templates/crd-serviceresolvers.yaml index 99cc1bb090..a18cc94de4 100644 --- a/charts/consul/templates/crd-serviceresolvers.yaml +++ b/charts/consul/templates/crd-serviceresolvers.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: serviceresolvers.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: ServiceResolver @@ -228,12 +227,13 @@ spec: type: object type: object prioritizeByLocality: - description: PrioritizeByLocality contains the configuration for - locality aware routing. + description: PrioritizeByLocality controls whether the locality of + services within the local partition will be used to prioritize connectivity. properties: mode: - description: Mode specifies the behavior of PrioritizeByLocality - routing. Valid values are "", "none", and "failover". + description: 'Mode specifies the type of prioritization that will + be performed when selecting nodes in the local partition. Valid + values are: "" (default "none"), "none", and "failover".' type: string type: object redirect: @@ -275,6 +275,10 @@ spec: If empty the default subset is used. type: string type: object + requestTimeout: + description: RequestTimeout is the timeout for receiving an HTTP response + from this service before the connection is terminated. + type: string subsets: additionalProperties: properties: diff --git a/charts/consul/templates/crd-servicerouters.yaml b/charts/consul/templates/crd-servicerouters.yaml index 0157f646b4..c5ba99466c 100644 --- a/charts/consul/templates/crd-servicerouters.yaml +++ b/charts/consul/templates/crd-servicerouters.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: servicerouters.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: ServiceRouter diff --git a/charts/consul/templates/crd-servicesplitters.yaml b/charts/consul/templates/crd-servicesplitters.yaml index 18fb10341e..abe3ac85cc 100644 --- a/charts/consul/templates/crd-servicesplitters.yaml +++ b/charts/consul/templates/crd-servicesplitters.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: servicesplitters.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: ServiceSplitter diff --git a/charts/consul/templates/crd-tcproutes.yaml b/charts/consul/templates/crd-tcproutes.yaml index b5bc7be13c..a17f457a78 100644 --- a/charts/consul/templates/crd-tcproutes.yaml +++ b/charts/consul/templates/crd-tcproutes.yaml @@ -1,4 +1,7 @@ {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-terminatinggateways.yaml b/charts/consul/templates/crd-terminatinggateways.yaml index 955496aeee..cd58d1679c 100644 --- a/charts/consul/templates/crd-terminatinggateways.yaml +++ b/charts/consul/templates/crd-terminatinggateways.yaml @@ -4,16 +4,15 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: terminatinggateways.consul.hashicorp.com +spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd -spec: group: consul.hashicorp.com names: kind: TerminatingGateway diff --git a/charts/consul/templates/crd-tlsroutes.yaml b/charts/consul/templates/crd-tlsroutes.yaml index 1acd1b973a..be72f47d65 100644 --- a/charts/consul/templates/crd-tlsroutes.yaml +++ b/charts/consul/templates/crd-tlsroutes.yaml @@ -1,4 +1,7 @@ {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-udproutes.yaml b/charts/consul/templates/crd-udproutes.yaml index 0661b24c1a..fe331cca30 100644 --- a/charts/consul/templates/crd-udproutes.yaml +++ b/charts/consul/templates/crd-udproutes.yaml @@ -1,4 +1,7 @@ {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/control-plane/api/v1alpha1/serviceresolver_types.go b/control-plane/api/v1alpha1/serviceresolver_types.go index e5ce3c6fa6..714cd94c2a 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types.go +++ b/control-plane/api/v1alpha1/serviceresolver_types.go @@ -76,6 +76,9 @@ type ServiceResolverSpec struct { // ConnectTimeout is the timeout for establishing new network connections // to this service. ConnectTimeout metav1.Duration `json:"connectTimeout,omitempty"` + // RequestTimeout is the timeout for receiving an HTTP response from this + // service before the connection is terminated. + RequestTimeout metav1.Duration `json:"requestTimeout,omitempty"` // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty"` @@ -317,6 +320,7 @@ func (in *ServiceResolver) ToConsul(datacenter string) capi.ConfigEntry { Redirect: in.Spec.Redirect.toConsul(), Failover: in.Spec.Failover.toConsul(), ConnectTimeout: in.Spec.ConnectTimeout.Duration, + RequestTimeout: in.Spec.RequestTimeout.Duration, LoadBalancer: in.Spec.LoadBalancer.toConsul(), PrioritizeByLocality: in.Spec.PrioritizeByLocality.toConsul(), Meta: meta(datacenter), diff --git a/control-plane/api/v1alpha1/serviceresolver_types_test.go b/control-plane/api/v1alpha1/serviceresolver_types_test.go index 3a3d5a6016..11751aaa2a 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types_test.go +++ b/control-plane/api/v1alpha1/serviceresolver_types_test.go @@ -104,6 +104,7 @@ func TestServiceResolver_MatchesConsul(t *testing.T) { }, }, ConnectTimeout: metav1.Duration{Duration: 1 * time.Second}, + RequestTimeout: metav1.Duration{Duration: 1 * time.Second}, LoadBalancer: &LoadBalancer{ Policy: "policy", RingHashConfig: &RingHashConfig{ @@ -188,6 +189,7 @@ func TestServiceResolver_MatchesConsul(t *testing.T) { }, }, ConnectTimeout: 1 * time.Second, + RequestTimeout: 1 * time.Second, LoadBalancer: &capi.LoadBalancer{ Policy: "policy", RingHashConfig: &capi.RingHashConfig{ @@ -321,6 +323,7 @@ func TestServiceResolver_ToConsul(t *testing.T) { }, }, ConnectTimeout: metav1.Duration{Duration: 1 * time.Second}, + RequestTimeout: metav1.Duration{Duration: 1 * time.Second}, LoadBalancer: &LoadBalancer{ Policy: "policy", RingHashConfig: &RingHashConfig{ @@ -405,6 +408,7 @@ func TestServiceResolver_ToConsul(t *testing.T) { }, }, ConnectTimeout: 1 * time.Second, + RequestTimeout: 1 * time.Second, LoadBalancer: &capi.LoadBalancer{ Policy: "policy", RingHashConfig: &capi.RingHashConfig{ diff --git a/control-plane/api/v1alpha1/zz_generated.deepcopy.go b/control-plane/api/v1alpha1/zz_generated.deepcopy.go index 0787f24097..05000031ad 100644 --- a/control-plane/api/v1alpha1/zz_generated.deepcopy.go +++ b/control-plane/api/v1alpha1/zz_generated.deepcopy.go @@ -126,6 +126,7 @@ func (in *ControlPlaneRequestLimitList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ControlPlaneRequestLimitSpec) DeepCopyInto(out *ControlPlaneRequestLimitSpec) { *out = *in + out.ReadWriteRatesConfig = in.ReadWriteRatesConfig if in.ACL != nil { in, out := &in.ACL, &out.ACL *out = new(ReadWriteRatesConfig) @@ -928,6 +929,78 @@ func (in *IntentionHTTPPermission) DeepCopy() *IntentionHTTPPermission { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntentionJWTClaimVerification) DeepCopyInto(out *IntentionJWTClaimVerification) { + *out = *in + if in.Path != nil { + in, out := &in.Path, &out.Path + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntentionJWTClaimVerification. +func (in *IntentionJWTClaimVerification) DeepCopy() *IntentionJWTClaimVerification { + if in == nil { + return nil + } + out := new(IntentionJWTClaimVerification) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntentionJWTProvider) DeepCopyInto(out *IntentionJWTProvider) { + *out = *in + if in.VerifyClaims != nil { + in, out := &in.VerifyClaims, &out.VerifyClaims + *out = make([]*IntentionJWTClaimVerification, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(IntentionJWTClaimVerification) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntentionJWTProvider. +func (in *IntentionJWTProvider) DeepCopy() *IntentionJWTProvider { + if in == nil { + return nil + } + out := new(IntentionJWTProvider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntentionJWTRequirement) DeepCopyInto(out *IntentionJWTRequirement) { + *out = *in + if in.Providers != nil { + in, out := &in.Providers, &out.Providers + *out = make([]*IntentionJWTProvider, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(IntentionJWTProvider) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntentionJWTRequirement. +func (in *IntentionJWTRequirement) DeepCopy() *IntentionJWTRequirement { + if in == nil { + return nil + } + out := new(IntentionJWTRequirement) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IntentionPermission) DeepCopyInto(out *IntentionPermission) { *out = *in @@ -936,6 +1009,11 @@ func (in *IntentionPermission) DeepCopyInto(out *IntentionPermission) { *out = new(IntentionHTTPPermission) (*in).DeepCopyInto(*out) } + if in.JWT != nil { + in, out := &in.JWT, &out.JWT + *out = new(IntentionJWTRequirement) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntentionPermission. @@ -1123,6 +1201,31 @@ func (in *JWTLocationQueryParam) DeepCopy() *JWTLocationQueryParam { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in JWTLocations) DeepCopyInto(out *JWTLocations) { + { + in := &in + *out = make(JWTLocations, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(JWTLocation) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JWTLocations. +func (in JWTLocations) DeepCopy() JWTLocations { + if in == nil { + return nil + } + out := new(JWTLocations) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *JWTProvider) DeepCopyInto(out *JWTProvider) { *out = *in @@ -1952,6 +2055,21 @@ func (in *ProxyDefaultsSpec) DeepCopy() *ProxyDefaultsSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ReadWriteRatesConfig) DeepCopyInto(out *ReadWriteRatesConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadWriteRatesConfig. +func (in *ReadWriteRatesConfig) DeepCopy() *ReadWriteRatesConfig { + if in == nil { + return nil + } + out := new(ReadWriteRatesConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RemoteJWKS) DeepCopyInto(out *RemoteJWKS) { *out = *in @@ -1987,20 +2105,6 @@ func (in *RetryPolicyBackOff) DeepCopy() *RetryPolicyBackOff { return out } -func (in *ReadWriteRatesConfig) DeepCopyInto(out *ReadWriteRatesConfig) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadWriteRatesConfig. -func (in *ReadWriteRatesConfig) DeepCopy() *ReadWriteRatesConfig { - if in == nil { - return nil - } - out := new(ReadWriteRatesConfig) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *RingHashConfig) DeepCopyInto(out *RingHashConfig) { *out = *in @@ -2372,6 +2476,11 @@ func (in *ServiceIntentionsSpec) DeepCopyInto(out *ServiceIntentionsSpec) { } } } + if in.JWT != nil { + in, out := &in.JWT, &out.JWT + *out = new(IntentionJWTRequirement) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceIntentionsSpec. @@ -2509,6 +2618,21 @@ func (in *ServiceResolverList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceResolverPrioritizeByLocality) DeepCopyInto(out *ServiceResolverPrioritizeByLocality) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceResolverPrioritizeByLocality. +func (in *ServiceResolverPrioritizeByLocality) DeepCopy() *ServiceResolverPrioritizeByLocality { + if in == nil { + return nil + } + out := new(ServiceResolverPrioritizeByLocality) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceResolverRedirect) DeepCopyInto(out *ServiceResolverRedirect) { *out = *in @@ -2547,11 +2671,17 @@ func (in *ServiceResolverSpec) DeepCopyInto(out *ServiceResolverSpec) { } } out.ConnectTimeout = in.ConnectTimeout + out.RequestTimeout = in.RequestTimeout if in.LoadBalancer != nil { in, out := &in.LoadBalancer, &out.LoadBalancer *out = new(LoadBalancer) (*in).DeepCopyInto(*out) } + if in.PrioritizeByLocality != nil { + in, out := &in.PrioritizeByLocality, &out.PrioritizeByLocality + *out = new(ServiceResolverPrioritizeByLocality) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceResolverSpec. diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_controlplanerequestlimits.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_controlplanerequestlimits.yaml index 2eef465ada..4d1d808428 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_controlplanerequestlimits.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_controlplanerequestlimits.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: controlplanerequestlimits.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml index f066c90612..dac72f3646 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: exportedservices.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_gatewayclassconfigs.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_gatewayclassconfigs.yaml index a8393cd8fd..44eff52492 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_gatewayclassconfigs.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_gatewayclassconfigs.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: gatewayclassconfigs.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_ingressgateways.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_ingressgateways.yaml index f7ccf205d9..e9cf081721 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_ingressgateways.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_ingressgateways.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: ingressgateways.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_jwtproviders.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_jwtproviders.yaml index 8ca1ec0748..7506cc57dc 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_jwtproviders.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_jwtproviders.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: jwtproviders.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_meshes.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_meshes.yaml index bc46b6ab37..16dd398f99 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_meshes.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_meshes.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: meshes.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_meshservices.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_meshservices.yaml index 0871fc32e5..125883bdc5 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_meshservices.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_meshservices.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: meshservices.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_peeringacceptors.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_peeringacceptors.yaml index f6f9eda72b..894228a218 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_peeringacceptors.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_peeringacceptors.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: peeringacceptors.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_peeringdialers.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_peeringdialers.yaml index 7e0927c169..51c3e38319 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_peeringdialers.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_peeringdialers.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: peeringdialers.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_proxydefaults.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_proxydefaults.yaml index 7396816f7e..1be3b37703 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_proxydefaults.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_proxydefaults.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: proxydefaults.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_samenessgroups.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_samenessgroups.yaml index 23de092485..259ca7b910 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_samenessgroups.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_samenessgroups.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: samenessgroups.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_servicedefaults.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_servicedefaults.yaml index a5501a98d2..83503f11f3 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_servicedefaults.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_servicedefaults.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: servicedefaults.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_serviceintentions.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_serviceintentions.yaml index cd28173ba8..9553c73450 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_serviceintentions.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_serviceintentions.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: serviceintentions.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml index ec52c04e05..b83a859dc4 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: serviceresolvers.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -224,12 +223,13 @@ spec: type: object type: object prioritizeByLocality: - description: PrioritizeByLocality contains the configuration for - locality aware routing. + description: PrioritizeByLocality controls whether the locality of + services within the local partition will be used to prioritize connectivity. properties: mode: - description: Mode specifies the behavior of PrioritizeByLocality - routing. Valid values are "", "none", and "failover". + description: 'Mode specifies the type of prioritization that will + be performed when selecting nodes in the local partition. Valid + values are: "" (default "none"), "none", and "failover".' type: string type: object redirect: @@ -271,6 +271,10 @@ spec: If empty the default subset is used. type: string type: object + requestTimeout: + description: RequestTimeout is the timeout for receiving an HTTP response + from this service before the connection is terminated. + type: string subsets: additionalProperties: properties: diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml index 5919e23005..04590cc007 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: servicerouters.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml index d5848ed6ec..3a47472ba7 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: servicesplitters.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_terminatinggateways.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_terminatinggateways.yaml index 4910e42829..acf61cde4c 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_terminatinggateways.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_terminatinggateways.yaml @@ -6,8 +6,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.10.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.12.0 name: terminatinggateways.consul.hashicorp.com spec: group: consul.hashicorp.com diff --git a/control-plane/config/rbac/role.yaml b/control-plane/config/rbac/role.yaml index 7f90780e02..74328a8ae3 100644 --- a/control-plane/config/rbac/role.yaml +++ b/control-plane/config/rbac/role.yaml @@ -1,11 +1,7 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: manager-role rules: - apiGroups: diff --git a/control-plane/config/webhook/manifests.yaml b/control-plane/config/webhook/manifests.yaml index 0861f9253a..a515888527 100644 --- a/control-plane/config/webhook/manifests.yaml +++ b/control-plane/config/webhook/manifests.yaml @@ -1,11 +1,7 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - --- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: - creationTimestamp: null name: mutating-webhook-configuration webhooks: - admissionReviewVersions: From 94414a72dc3ed576621c31ce2f75d4d6bc214d54 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Wed, 26 Jul 2023 10:32:57 -0400 Subject: [PATCH 091/120] Increase timeout for acl replication to 60 seconds and poll every 500 ms (#2656) increase timeout for acl replication to 60 seconds and poll every 500 ms --- .changelog/2656.txt | 3 +++ control-plane/subcommand/common/common.go | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 .changelog/2656.txt diff --git a/.changelog/2656.txt b/.changelog/2656.txt new file mode 100644 index 0000000000..07436087d3 --- /dev/null +++ b/.changelog/2656.txt @@ -0,0 +1,3 @@ +```release-note:improvement +control-plane: increase timeout after login for ACL replication to 60 seconds +``` \ No newline at end of file diff --git a/control-plane/subcommand/common/common.go b/control-plane/subcommand/common/common.go index 598ba66ea5..1636c0b10e 100644 --- a/control-plane/subcommand/common/common.go +++ b/control-plane/subcommand/common/common.go @@ -39,8 +39,8 @@ const ( // The number of times to attempt ACL Login. numLoginRetries = 100 - raftReplicationTimeout = 2 * time.Second - tokenReadPollingInterval = 100 * time.Millisecond + raftReplicationTimeout = 60 * time.Second + tokenReadPollingInterval = 500 * time.Millisecond ) // Logger returns an hclog instance with log level set and JSON logging enabled/disabled, or an error if level is invalid. From 596a2a78d8e512003f2f4855d4cd312d79910f81 Mon Sep 17 00:00:00 2001 From: Paul Glass Date: Wed, 26 Jul 2023 15:24:38 -0500 Subject: [PATCH 092/120] Update changelog to address cloud auto-join change in 1.0.0 (#2667) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54bdba549b..0d60f91b67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -404,6 +404,7 @@ BREAKING CHANGES: * `client.enabled` now defaults to `false`. Setting it to `true` will deploy client agents, however, none of the consul-k8s components will use clients for their operation. * `global.imageEnvoy` is no longer used for sidecar proxies, as well as mesh, terminating, and ingress gateways. * `externalServers.grpcPort` default is now `8502` instead of `8503`. + * `externalServers.hosts` no longer supports [cloud auto-join](https://developer.hashicorp.com/consul/docs/install/cloud-auto-join) strings directly. Instead, include an [`exec=`](https://github.com/hashicorp/go-netaddrs#command-line-tool-usage) string in the `externalServers.hosts` list to invoke the `discover` CLI. For example, the following string invokes the `discover` CLI with a cloud auto-join string: `exec=discover -q addrs provider=aws region=us-west-2 tag_key=consul-server tag_value=true`. The `discover` CLI is included in the official `hashicorp/consul-dataplane` images by default. * `meshGateway.service.enabled` value is removed. Mesh gateways now will always have a Kubernetes service as this is required to register them as a service with Consul. * `meshGateway.initCopyConsulContainer`, `ingressGateways.initCopyConsulContainer`, `terminatingGateways.initCopyConsulContainer` values are removed. * `connectInject.enabled` now defaults to `true`. [[GH-1551](https://github.com/hashicorp/consul-k8s/pull/1551)] From f026d439b553071444899edcde8925ac4f317cc7 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Wed, 26 Jul 2023 17:22:46 -0500 Subject: [PATCH 093/120] NET-4967: Fix helm install when setting copyAnnotations or nodeSelector for apiGateway (#2597) * Support multiline nodeSelector arg * Support multiline service annotations arg * Update test assertions * Add changelog entry --- .changelog/2597.txt | 3 +++ .../consul/templates/gateway-resources-job.yaml | 6 ++++-- .../consul/test/unit/gateway-resources-job.bats | 16 +++++++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 .changelog/2597.txt diff --git a/.changelog/2597.txt b/.changelog/2597.txt new file mode 100644 index 0000000000..83cc369b6d --- /dev/null +++ b/.changelog/2597.txt @@ -0,0 +1,3 @@ +```release-note:bug +api-gateway: fix helm install when setting copyAnnotations or nodeSelector +``` diff --git a/charts/consul/templates/gateway-resources-job.yaml b/charts/consul/templates/gateway-resources-job.yaml index 3a29f75e66..1fa712759d 100644 --- a/charts/consul/templates/gateway-resources-job.yaml +++ b/charts/consul/templates/gateway-resources-job.yaml @@ -88,13 +88,15 @@ spec: {{- end}} {{- end}} {{- if .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector }} - - -node-selector={{ .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector }} + - -node-selector + - {{- toYaml .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector | nindent 14 -}} {{- end }} {{- if .Values.connectInject.apiGateway.managedGatewayClass.tolerations }} - -tolerations={{ .Values.connectInject.apiGateway.managedGatewayClass.tolerations }} {{- end }} {{- if .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service }} - - -service-annotations={{ .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service.annotations }} + - -service-annotations + - {{- toYaml .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service.annotations | nindent 14 -}} {{- end }} - -service-type={{ .Values.connectInject.apiGateway.managedGatewayClass.serviceType }} {{- end}} diff --git a/charts/consul/test/unit/gateway-resources-job.bats b/charts/consul/test/unit/gateway-resources-job.bats index 27bba00ed5..d79838770d 100644 --- a/charts/consul/test/unit/gateway-resources-job.bats +++ b/charts/consul/test/unit/gateway-resources-job.bats @@ -107,14 +107,20 @@ target=templates/gateway-resources-job.yaml local actual=$(echo "$spec" | jq 'any(index("-service-type=Foo"))') [ "${actual}" = "true" ] - local actual=$(echo "$spec" | jq '.[12] | ."-node-selector=foo"') - [ "${actual}" = "\"bar\"" ] + local actual=$(echo "$spec" | jq '.[12]') + [ "${actual}" = "\"-node-selector\"" ] + + local actual=$(echo "$spec" | jq '.[13]') + [ "${actual}" = "\"foo: bar\"" ] - local actual=$(echo "$spec" | jq '.[13] | ."-tolerations=- key"') + local actual=$(echo "$spec" | jq '.[14] | ."-tolerations=- key"') [ "${actual}" = "\"bar\"" ] - local actual=$(echo "$spec" | jq '.[14]') - [ "${actual}" = "\"-service-annotations=- bingo\"" ] + local actual=$(echo "$spec" | jq '.[15]') + [ "${actual}" = "\"-service-annotations\"" ] + + local actual=$(echo "$spec" | jq '.[16]') + [ "${actual}" = "\"- bingo\"" ] } From 7bb0a57aec89dbdab4a6313536ae4de540e43d5f Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Thu, 27 Jul 2023 09:47:02 -0400 Subject: [PATCH 094/120] Fix ordering of licence in templates (#2675) --- charts/consul/templates/crd-gatewayclasses.yaml | 3 ++- charts/consul/templates/crd-gateways.yaml | 3 ++- charts/consul/templates/crd-grpcroutes.yaml | 3 ++- charts/consul/templates/crd-httproutes.yaml | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/charts/consul/templates/crd-gatewayclasses.yaml b/charts/consul/templates/crd-gatewayclasses.yaml index 8f381a7065..b0725c2baf 100644 --- a/charts/consul/templates/crd-gatewayclasses.yaml +++ b/charts/consul/templates/crd-gatewayclasses.yaml @@ -1,6 +1,7 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} + apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-gateways.yaml b/charts/consul/templates/crd-gateways.yaml index d9c381b1de..923a75477d 100644 --- a/charts/consul/templates/crd-gateways.yaml +++ b/charts/consul/templates/crd-gateways.yaml @@ -1,6 +1,7 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} + apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-grpcroutes.yaml b/charts/consul/templates/crd-grpcroutes.yaml index cc126d73c3..07412ba60b 100644 --- a/charts/consul/templates/crd-grpcroutes.yaml +++ b/charts/consul/templates/crd-grpcroutes.yaml @@ -1,6 +1,7 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} + apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-httproutes.yaml b/charts/consul/templates/crd-httproutes.yaml index 5f45528567..d9055e7406 100644 --- a/charts/consul/templates/crd-httproutes.yaml +++ b/charts/consul/templates/crd-httproutes.yaml @@ -1,6 +1,7 @@ +{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -{{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} + apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: From b6d3e61058e60e8dc644c3de66a0d186123d907e Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Thu, 27 Jul 2023 13:48:26 -0700 Subject: [PATCH 095/120] Mw/net 4260 phase 2 automate the k8s sameness tests (#2579) * add kustomize files - These reflect the different test cases - sameness.yaml defines the ordered list of failovers - static-server responds with a unique name so we can track failover order - static-client includes both DNS and CURL in the image used so we can exec in for testing * add sameness tests - We do a bunch of infra setup for peering and partitions, but after the initial setup only partitions are tested - We test service failover, dns failover and PQ failover scenarios * add 4 kind clusters to make target - The sameness tests require 4 kind clusters, so the make target will now spin up 4 kind clusters - not all tests need 4 kind clusters, but the entire suite of tests can be run with 4 * increase kubectl timeout to 90s - add variable for configuring timeout - timeout was triggering locally on intel mac machine, so this timeout should cover our devs lowest performing machines * add sameness test to test packages * Fix comments on partition connect test --- Makefile | 16 +- .../kind_acceptance_test_packages.yaml | 9 +- acceptance/framework/k8s/kubectl.go | 15 +- .../sameness/default-ns/kustomization.yaml | 5 + .../bases/sameness/default-ns/sameness.yaml | 12 + .../exportedservices-ap1.yaml | 9 + .../exportedservices-ap1/kustomization.yaml | 5 + .../sameness/override-ns/intentions.yaml | 12 + .../sameness/override-ns/kustomization.yaml | 7 + .../override-ns/payment-service-resolver.yaml | 13 + .../override-ns/service-defaults.yaml | 6 + .../bases/sameness/peering/kustomization.yaml | 5 + .../fixtures/bases/sameness/peering/mesh.yaml | 7 + .../ap1-partition/kustomization.yaml | 8 + .../ap1-partition/patch.yaml | 16 + .../default-partition/kustomization.yaml | 8 + .../default-partition/patch.yaml | 16 + .../static-client/default/kustomization.yaml | 8 + .../sameness/static-client/default/patch.yaml | 22 + .../partition/kustomization.yaml | 8 + .../static-client/partition/patch.yaml | 22 + .../static-server/default/kustomization.yaml | 8 + .../sameness/static-server/default/patch.yaml | 23 + .../partition/kustomization.yaml | 8 + .../static-server/partition/patch.yaml | 23 + .../partitions/partitions_connect_test.go | 4 +- acceptance/tests/sameness/main_test.go | 28 ++ acceptance/tests/sameness/sameness_test.go | 454 ++++++++++++++++++ 28 files changed, 764 insertions(+), 13 deletions(-) create mode 100644 acceptance/tests/fixtures/bases/sameness/default-ns/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/exportedservices-ap1/exportedservices-ap1.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/exportedservices-ap1/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/override-ns/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-client/default/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-client/default/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-client/partition/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-client/partition/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-server/default/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-server/default/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-server/partition/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-server/partition/patch.yaml create mode 100644 acceptance/tests/sameness/main_test.go create mode 100644 acceptance/tests/sameness/sameness_test.go diff --git a/Makefile b/Makefile index 4289b81b9b..e2c39de2ea 100644 --- a/Makefile +++ b/Makefile @@ -130,22 +130,26 @@ kind-cni-calico: kubectl create -f $(CURDIR)/acceptance/framework/environment/cni-kind/custom-resources.yaml @sleep 20 -# Helper target for doing local cni acceptance testing -kind-cni: +kind-delete: kind delete cluster --name dc1 kind delete cluster --name dc2 + kind delete cluster --name dc3 + kind delete cluster --name dc4 + + +# Helper target for doing local cni acceptance testing +kind-cni: kind-delete kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc1 --image $(KIND_NODE_IMAGE) make kind-cni-calico kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc2 --image $(KIND_NODE_IMAGE) make kind-cni-calico # Helper target for doing local acceptance testing -kind: - kind delete cluster --name dc1 - kind delete cluster --name dc2 +kind: kind-delete kind create cluster --name dc1 --image $(KIND_NODE_IMAGE) kind create cluster --name dc2 --image $(KIND_NODE_IMAGE) - + kind create cluster --name dc3 --image $(KIND_NODE_IMAGE) + kind create cluster --name dc4 --image $(KIND_NODE_IMAGE) # ===========> Shared Targets diff --git a/acceptance/ci-inputs/kind_acceptance_test_packages.yaml b/acceptance/ci-inputs/kind_acceptance_test_packages.yaml index 8677b83c4e..e0e126bbda 100644 --- a/acceptance/ci-inputs/kind_acceptance_test_packages.yaml +++ b/acceptance/ci-inputs/kind_acceptance_test_packages.yaml @@ -3,7 +3,8 @@ - {runner: 0, test-packages: "partitions"} - {runner: 1, test-packages: "peering"} -- {runner: 2, test-packages: "connect snapshot-agent wan-federation"} -- {runner: 3, test-packages: "cli vault metrics"} -- {runner: 4, test-packages: "api-gateway ingress-gateway sync example consul-dns"} -- {runner: 5, test-packages: "config-entries terminating-gateway basic"} \ No newline at end of file +- {runner: 2, test-packages: "sameness"} +- {runner: 3, test-packages: "connect snapshot-agent wan-federation"} +- {runner: 4, test-packages: "cli vault metrics"} +- {runner: 5, test-packages: "api-gateway ingress-gateway sync example consul-dns"} +- {runner: 6, test-packages: "config-entries terminating-gateway basic"} diff --git a/acceptance/framework/k8s/kubectl.go b/acceptance/framework/k8s/kubectl.go index ea90212e04..acfedbdb3d 100644 --- a/acceptance/framework/k8s/kubectl.go +++ b/acceptance/framework/k8s/kubectl.go @@ -4,6 +4,7 @@ package k8s import ( + "fmt" "strings" "testing" "time" @@ -16,6 +17,10 @@ import ( "github.com/stretchr/testify/require" ) +const ( + kubectlTimeout = "--timeout=120s" +) + // kubeAPIConnectErrs are errors that sometimes occur when talking to the // Kubernetes API related to connection issues. var kubeAPIConnectErrs = []string{ @@ -97,7 +102,7 @@ func KubectlApplyK(t *testing.T, options *k8s.KubectlOptions, kustomizeDir strin // deletes it from the cluster by running 'kubectl delete -f'. // If there's an error deleting the file, fail the test. func KubectlDelete(t *testing.T, options *k8s.KubectlOptions, configPath string) { - _, err := RunKubectlAndGetOutputE(t, options, "delete", "--timeout=60s", "-f", configPath) + _, err := RunKubectlAndGetOutputE(t, options, "delete", kubectlTimeout, "-f", configPath) require.NoError(t, err) } @@ -107,7 +112,13 @@ func KubectlDelete(t *testing.T, options *k8s.KubectlOptions, configPath string) func KubectlDeleteK(t *testing.T, options *k8s.KubectlOptions, kustomizeDir string) { // Ignore not found errors because Kubernetes automatically cleans up the kube secrets that we deployed // referencing the ServiceAccount when it is deleted. - _, err := RunKubectlAndGetOutputE(t, options, "delete", "--timeout=60s", "--ignore-not-found", "-k", kustomizeDir) + _, err := RunKubectlAndGetOutputE(t, options, "delete", kubectlTimeout, "--ignore-not-found", "-k", kustomizeDir) + require.NoError(t, err) +} + +// KubectlScale takes a deployment and scales it to the provided number of replicas. +func KubectlScale(t *testing.T, options *k8s.KubectlOptions, deployment string, replicas int) { + _, err := RunKubectlAndGetOutputE(t, options, "scale", kubectlTimeout, fmt.Sprintf("--replicas=%d", replicas), deployment) require.NoError(t, err) } diff --git a/acceptance/tests/fixtures/bases/sameness/default-ns/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/default-ns/kustomization.yaml new file mode 100644 index 0000000000..3f9d23c28a --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/default-ns/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - sameness.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml b/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml new file mode 100644 index 0000000000..0eb7d9e008 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml @@ -0,0 +1,12 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: SamenessGroup +metadata: + name: mine +spec: + members: + - partition: default + - partition: ap1 + - peer: cluster-01-a + - peer: cluster-01-b + - peer: cluster-02-a + - peer: cluster-03-a diff --git a/acceptance/tests/fixtures/bases/sameness/exportedservices-ap1/exportedservices-ap1.yaml b/acceptance/tests/fixtures/bases/sameness/exportedservices-ap1/exportedservices-ap1.yaml new file mode 100644 index 0000000000..3dc494dd43 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/exportedservices-ap1/exportedservices-ap1.yaml @@ -0,0 +1,9 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ExportedServices +metadata: + name: ap1 +spec: + services: [] diff --git a/acceptance/tests/fixtures/bases/sameness/exportedservices-ap1/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/exportedservices-ap1/kustomization.yaml new file mode 100644 index 0000000000..1793fa6db7 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/exportedservices-ap1/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - exportedservices-ap1.yaml diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml new file mode 100644 index 0000000000..425b9fe21d --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml @@ -0,0 +1,12 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceIntentions +metadata: + name: static-server +spec: + destination: + name: static-server + sources: + - name: static-client + namespace: ns1 + samenessGroup: mine + action: allow diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/kustomization.yaml new file mode 100644 index 0000000000..adfd1c827b --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/kustomization.yaml @@ -0,0 +1,7 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - intentions.yaml + - payment-service-resolver.yaml + - service-defaults.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml new file mode 100644 index 0000000000..b2b6b68c3d --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml @@ -0,0 +1,13 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceResolver +metadata: + name: static-server +spec: + connectTimeout: 15s + failover: + '*': + samenessGroup: mine + policy: + mode: order-by-locality + regions: + - us-west-2 diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml new file mode 100644 index 0000000000..f88d143728 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml @@ -0,0 +1,6 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ServiceDefaults +metadata: + name: static-server +spec: + protocol: http \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/peering/kustomization.yaml new file mode 100644 index 0000000000..926e91236d --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - mesh.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml b/acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml new file mode 100644 index 0000000000..de84382d3e --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml @@ -0,0 +1,7 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: Mesh +metadata: + name: mesh +spec: + peering: + peerThroughMeshGateways: true diff --git a/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/kustomization.yaml new file mode 100644 index 0000000000..2a2f47a332 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/sameness/exportedservices-ap1 + +patchesStrategicMerge: +- patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/patch.yaml b/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/patch.yaml new file mode 100644 index 0000000000..d71e8211ba --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/patch.yaml @@ -0,0 +1,16 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ExportedServices +metadata: + name: ap1 +spec: + services: + - name: static-server + namespace: ns2 + consumers: + - samenessGroup: mine + - name: mesh-gateway + consumers: + - samenessGroup: mine diff --git a/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/kustomization.yaml new file mode 100644 index 0000000000..05de6151fc --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/exportedservices-default + +patchesStrategicMerge: +- patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/patch.yaml b/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/patch.yaml new file mode 100644 index 0000000000..9bb440637e --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/patch.yaml @@ -0,0 +1,16 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ExportedServices +metadata: + name: default +spec: + services: + - name: static-server + namespace: ns2 + consumers: + - samenessGroup: mine + - name: mesh-gateway + consumers: + - samenessGroup: mine diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/default/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/default/kustomization.yaml new file mode 100644 index 0000000000..227f223c9f --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-client/default/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/static-client + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/default/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/default/patch.yaml new file mode 100644 index 0000000000..1775e9abb1 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-client/default/patch.yaml @@ -0,0 +1,22 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-client +spec: + template: + metadata: + annotations: + 'consul.hashicorp.com/connect-inject': 'true' + 'consul.hashicorp.com/connect-service-upstreams': 'static-server.ns2.default:8080' + spec: + containers: + - name: static-client + image: anubhavmishra/tiny-tools:latest + # Just spin & wait forever, we'll use `kubectl exec` to demo + command: ['/bin/sh', '-c', '--'] + args: ['while true; do sleep 30; done;'] + # If ACLs are enabled, the serviceAccountName must match the Consul service name. + serviceAccountName: static-client \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/partition/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/partition/kustomization.yaml new file mode 100644 index 0000000000..227f223c9f --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-client/partition/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/static-client + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/partition/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/partition/patch.yaml new file mode 100644 index 0000000000..c1a14c6070 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-client/partition/patch.yaml @@ -0,0 +1,22 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-client +spec: + template: + metadata: + annotations: + 'consul.hashicorp.com/connect-inject': 'true' + 'consul.hashicorp.com/connect-service-upstreams': 'static-server.ns2.ap1:8080' + spec: + containers: + - name: static-client + image: anubhavmishra/tiny-tools:latest + # Just spin & wait forever, we'll use `kubectl exec` to demo + command: ['/bin/sh', '-c', '--'] + args: ['while true; do sleep 30; done;'] + # If ACLs are enabled, the serviceAccountName must match the Consul service name. + serviceAccountName: static-client diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/default/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/default/kustomization.yaml new file mode 100644 index 0000000000..c15bfe7ba7 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-server/default/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/static-server + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/default/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/default/patch.yaml new file mode 100644 index 0000000000..ca27b7ba42 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-server/default/patch.yaml @@ -0,0 +1,23 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-server +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + spec: + containers: + - name: static-server + image: docker.mirror.hashicorp.services/hashicorp/http-echo:alpine + args: + - -text="cluster-01-a" + - -listen=:8080 + ports: + - containerPort: 8080 + name: http + serviceAccountName: static-server diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/partition/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/partition/kustomization.yaml new file mode 100644 index 0000000000..c15bfe7ba7 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-server/partition/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/static-server + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/partition/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/partition/patch.yaml new file mode 100644 index 0000000000..044115d1d1 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-server/partition/patch.yaml @@ -0,0 +1,23 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-server +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + spec: + containers: + - name: static-server + image: docker.mirror.hashicorp.services/hashicorp/http-echo:alpine + args: + - -text="cluster-01-b" + - -listen=:8080 + ports: + - containerPort: 8080 + name: http + serviceAccountName: static-server diff --git a/acceptance/tests/partitions/partitions_connect_test.go b/acceptance/tests/partitions/partitions_connect_test.go index 6b103614c7..c53e5b6171 100644 --- a/acceptance/tests/partitions/partitions_connect_test.go +++ b/acceptance/tests/partitions/partitions_connect_test.go @@ -108,6 +108,7 @@ func TestPartitions_Connect(t *testing.T) { "dns.enableRedirection": strconv.FormatBool(cfg.EnableTransparentProxy), } + // Setup the default partition defaultPartitionHelmValues := make(map[string]string) // On Kind, there are no load balancers but since all clusters @@ -129,6 +130,7 @@ func TestPartitions_Connect(t *testing.T) { serverConsulCluster := consul.NewHelmCluster(t, defaultPartitionHelmValues, defaultPartitionClusterContext, cfg, releaseName) serverConsulCluster.Create(t) + // Copy secrets from the default partition to the secondary partition // Get the TLS CA certificate and key secret from the server cluster and apply it to the client cluster. caCertSecretName := fmt.Sprintf("%s-consul-ca-cert", releaseName) @@ -146,7 +148,7 @@ func TestPartitions_Connect(t *testing.T) { k8sAuthMethodHost := k8s.KubernetesAPIServerHost(t, cfg, secondaryPartitionClusterContext) - // Create client cluster. + // Create secondary partition cluster. secondaryPartitionHelmValues := map[string]string{ "global.enabled": "false", diff --git a/acceptance/tests/sameness/main_test.go b/acceptance/tests/sameness/main_test.go new file mode 100644 index 0000000000..67e6ee42b7 --- /dev/null +++ b/acceptance/tests/sameness/main_test.go @@ -0,0 +1,28 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package sameness + +import ( + "fmt" + "os" + "testing" + + testsuite "github.com/hashicorp/consul-k8s/acceptance/framework/suite" +) + +var suite testsuite.Suite + +func TestMain(m *testing.M) { + suite = testsuite.NewSuite(m) + + expectedNumberOfClusters := 4 + + if suite.Config().EnableMultiCluster && suite.Config().IsExpectedClusterCount(expectedNumberOfClusters) && suite.Config().UseKind { + os.Exit(suite.Run()) + } else { + fmt.Println(fmt.Sprintf("Skipping sameness tests because either -enable-multi-cluster is "+ + "not set, the number of clusters did not match the expected count of %d, or --useKind is false. "+ + "Sameness acceptance tests are currently only suopported on Kind clusters", expectedNumberOfClusters)) + } +} diff --git a/acceptance/tests/sameness/sameness_test.go b/acceptance/tests/sameness/sameness_test.go new file mode 100644 index 0000000000..a7a926cd42 --- /dev/null +++ b/acceptance/tests/sameness/sameness_test.go @@ -0,0 +1,454 @@ +package sameness + +import ( + "context" + "fmt" + "strconv" + "testing" + + terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/config" + "github.com/hashicorp/consul-k8s/acceptance/framework/consul" + "github.com/hashicorp/consul-k8s/acceptance/framework/environment" + "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" + "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" + "github.com/hashicorp/consul-k8s/acceptance/framework/logger" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + primaryDatacenterPartition = "ap1" + primaryServerDatacenter = "dc1" + peer1Datacenter = "dc2" + peer2Datacenter = "dc3" + staticClientNamespace = "ns1" + staticServerNamespace = "ns2" + + keyPrimaryServer = "server" + keyPartition = "partition" + keyPeer1 = "peer1" + keyPeer2 = "peer2" + + staticServerDeployment = "deploy/static-server" + staticClientDeployment = "deploy/static-client" + + primaryServerClusterName = "cluster-01-a" + partitionClusterName = "cluster-01-b" +) + +func TestFailover_Connect(t *testing.T) { + env := suite.Environment() + cfg := suite.Config() + + if !cfg.EnableEnterprise { + t.Skipf("skipping this test because -enable-enterprise is not set") + } + + cases := []struct { + name string + ACLsEnabled bool + }{ + { + "default failover", + false, + }, + { + "secure failover", + true, + }, + } + + for _, c := range cases { + t.Run(c.name, func(t *testing.T) { + /* + Architecture Overview: + Primary Datacenter (DC1) + Default Partition + Peer -> DC2 (cluster-02-a) + Peer -> DC3 (cluster-03-a) + AP1 Partition + Peer -> DC2 (cluster-02-a) + Peer -> DC3 (cluster-03-a) + Datacenter 2 (DC2) + Default Partition + Peer -> DC1 (cluster-01-a) + Peer -> DC1 (cluster-01-b) + Peer -> DC3 (cluster-03-a) + Datacenter 3 (DC3) + Default Partition + Peer -> DC1 (cluster-01-a) + Peer -> DC1 (cluster-01-b) + Peer -> DC2 (cluster-02-a) + + + Architecture Diagram + failover scenarios from perspective of DC1 Default Partition Static-Server + +-------------------------------------------+ + | | + | DC1 | + | | + | +-----------------------------+ | +-----------------------------------+ + | | | | | DC2 | + | | +------------------+ | | Failover 2 | +------------------+ | + | | | +-------+--------+-----------------+------>| | | + | | | Static-Server | | | | | Static-Server | | + | | | +-------+---+ | | | | | + | | | | | | | | | | | + | | | | | | | | | | | + | | | +-------+---+----+-------------+ | | | | + | | +------------------+ | | | | | +------------------+ | + | | Admin Partitions: Default | | | | | | + | | Name: cluster-01-a | | | | | Admin Partitions: Default | + | | | | | | | Name: cluster-02-a | + | +-----------------------------+ | | | | | + | | | | +-----------------------------------+ + | Failover 1| | Failover 3 | + | +-------------------------------+ | | | +-----------------------------------+ + | | | | | | | DC3 | + | | +------------------+ | | | | | +------------------+ | + | | | | | | | | | | Static-Server | | + | | | Static-Server | | | | | | | | | + | | | | | | | | | | | | + | | | | | | | +---+------>| | | + | | | |<------+--+ | | | | | + | | | | | | | +------------------+ | + | | +------------------+ | | | | + | | Admin Partitions: ap1 | | | Admin Partitions: Default | + | | Name: cluster-01-b | | | Name: cluster-03-a | + | | | | | | + | +-------------------------------+ | | | + | | +-----------------------------------+ + +-------------------------------------------+ + */ + + members := map[string]*member{ + keyPrimaryServer: {context: env.DefaultContext(t), hasServer: true}, + keyPartition: {context: env.Context(t, 1), hasServer: false}, + keyPeer1: {context: env.Context(t, 2), hasServer: true}, + keyPeer2: {context: env.Context(t, 3), hasServer: true}, + } + + // Setup Namespaces. + for _, v := range members { + createNamespaces(t, cfg, v.context) + } + + // Create the Default Cluster. + commonHelmValues := map[string]string{ + "global.peering.enabled": "true", + + "global.tls.enabled": "true", + "global.tls.httpsOnly": strconv.FormatBool(c.ACLsEnabled), + + "global.enableConsulNamespaces": "true", + + "global.adminPartitions.enabled": "true", + + "global.logLevel": "debug", + + "global.acls.manageSystemACLs": strconv.FormatBool(c.ACLsEnabled), + + "connectInject.enabled": "true", + "connectInject.consulNamespaces.mirroringK8S": "true", + + "meshGateway.enabled": "true", + "meshGateway.replicas": "1", + + "dns.enabled": "true", + } + + defaultPartitionHelmValues := map[string]string{ + "global.datacenter": primaryServerDatacenter, + } + + // On Kind, there are no load balancers but since all clusters + // share the same node network (docker bridge), we can use + // a NodePort service so that we can access node(s) in a different Kind cluster. + if cfg.UseKind { + defaultPartitionHelmValues["meshGateway.service.type"] = "NodePort" + defaultPartitionHelmValues["meshGateway.service.nodePort"] = "30200" + defaultPartitionHelmValues["server.exposeService.type"] = "NodePort" + defaultPartitionHelmValues["server.exposeService.nodePort.https"] = "30000" + defaultPartitionHelmValues["server.exposeService.nodePort.grpc"] = "30100" + } + helpers.MergeMaps(defaultPartitionHelmValues, commonHelmValues) + + releaseName := helpers.RandomName() + members[keyPrimaryServer].helmCluster = consul.NewHelmCluster(t, defaultPartitionHelmValues, members[keyPrimaryServer].context, cfg, releaseName) + members[keyPrimaryServer].helmCluster.Create(t) + + // Get the TLS CA certificate and key secret from the server cluster and apply it to the client cluster. + caCertSecretName := fmt.Sprintf("%s-consul-ca-cert", releaseName) + + logger.Logf(t, "retrieving ca cert secret %s from the server cluster and applying to the client cluster", caCertSecretName) + k8s.CopySecret(t, members[keyPrimaryServer].context, members[keyPartition].context, caCertSecretName) + + // Create Secondary Partition Cluster which will apply the primary datacenter. + partitionToken := fmt.Sprintf("%s-consul-partitions-acl-token", releaseName) + if c.ACLsEnabled { + logger.Logf(t, "retrieving partition token secret %s from the server cluster and applying to the client cluster", partitionToken) + k8s.CopySecret(t, members[keyPrimaryServer].context, members[keyPartition].context, partitionToken) + } + + partitionServiceName := fmt.Sprintf("%s-consul-expose-servers", releaseName) + partitionSvcAddress := k8s.ServiceHost(t, cfg, members[keyPrimaryServer].context, partitionServiceName) + + k8sAuthMethodHost := k8s.KubernetesAPIServerHost(t, cfg, members[keyPartition].context) + + secondaryPartitionHelmValues := map[string]string{ + "global.enabled": "false", + "global.datacenter": primaryServerDatacenter, + + "global.adminPartitions.name": primaryDatacenterPartition, + + "global.tls.caCert.secretName": caCertSecretName, + "global.tls.caCert.secretKey": "tls.crt", + + "externalServers.enabled": "true", + "externalServers.hosts[0]": partitionSvcAddress, + "externalServers.tlsServerName": fmt.Sprintf("server.%s.consul", primaryServerDatacenter), + "global.server.enabled": "false", + } + + if c.ACLsEnabled { + // Setup partition token and auth method host if ACLs enabled. + secondaryPartitionHelmValues["global.acls.bootstrapToken.secretName"] = partitionToken + secondaryPartitionHelmValues["global.acls.bootstrapToken.secretKey"] = "token" + secondaryPartitionHelmValues["externalServers.k8sAuthMethodHost"] = k8sAuthMethodHost + } + + if cfg.UseKind { + secondaryPartitionHelmValues["externalServers.httpsPort"] = "30000" + secondaryPartitionHelmValues["externalServers.grpcPort"] = "30100" + secondaryPartitionHelmValues["meshGateway.service.type"] = "NodePort" + secondaryPartitionHelmValues["meshGateway.service.nodePort"] = "30200" + } + helpers.MergeMaps(secondaryPartitionHelmValues, commonHelmValues) + + members[keyPartition].helmCluster = consul.NewHelmCluster(t, secondaryPartitionHelmValues, members[keyPartition].context, cfg, releaseName) + members[keyPartition].helmCluster.Create(t) + + // Create Peer 1 Cluster. + PeerOneHelmValues := map[string]string{ + "global.datacenter": peer1Datacenter, + } + + if cfg.UseKind { + PeerOneHelmValues["server.exposeGossipAndRPCPorts"] = "true" + PeerOneHelmValues["meshGateway.service.type"] = "NodePort" + PeerOneHelmValues["meshGateway.service.nodePort"] = "30100" + } + helpers.MergeMaps(PeerOneHelmValues, commonHelmValues) + + members[keyPeer1].helmCluster = consul.NewHelmCluster(t, PeerOneHelmValues, members[keyPeer1].context, cfg, releaseName) + members[keyPeer1].helmCluster.Create(t) + + // Create Peer 2 Cluster. + PeerTwoHelmValues := map[string]string{ + "global.datacenter": peer2Datacenter, + } + + if cfg.UseKind { + PeerTwoHelmValues["server.exposeGossipAndRPCPorts"] = "true" + PeerTwoHelmValues["meshGateway.service.type"] = "NodePort" + PeerTwoHelmValues["meshGateway.service.nodePort"] = "30100" + } + helpers.MergeMaps(PeerTwoHelmValues, commonHelmValues) + + members[keyPeer2].helmCluster = consul.NewHelmCluster(t, PeerTwoHelmValues, members[keyPeer2].context, cfg, releaseName) + members[keyPeer2].helmCluster.Create(t) + + // Create a ProxyDefaults resource to configure services to use the mesh + // gateways and set server and client opts. + for k, v := range members { + logger.Logf(t, "applying resources on %s", v.context.KubectlOptions(t).ContextName) + + // Client will use the client namespace. + members[k].clientOpts = &terratestk8s.KubectlOptions{ + ContextName: v.context.KubectlOptions(t).ContextName, + ConfigPath: v.context.KubectlOptions(t).ConfigPath, + Namespace: staticClientNamespace, + } + + // Server will use the server namespace. + members[k].serverOpts = &terratestk8s.KubectlOptions{ + ContextName: v.context.KubectlOptions(t).ContextName, + ConfigPath: v.context.KubectlOptions(t).ConfigPath, + Namespace: staticServerNamespace, + } + + // Sameness Defaults need to be applied first so that the sameness group exists. + applyResources(t, cfg, "../fixtures/bases/mesh-gateway", members[k].context.KubectlOptions(t)) + applyResources(t, cfg, "../fixtures/bases/sameness/default-ns", members[k].context.KubectlOptions(t)) + applyResources(t, cfg, "../fixtures/bases/sameness/override-ns", members[k].serverOpts) + + // Only assign a client if the cluster is running a Consul server. + if v.hasServer { + members[k].client, _ = members[k].helmCluster.SetupConsulClient(t, c.ACLsEnabled) + } + } + + // TODO: Add further setup for peering, right now the rest of this test will only cover Partitions + // Create static server deployments. + logger.Log(t, "creating static-server and static-client deployments") + k8s.DeployKustomize(t, members[keyPrimaryServer].serverOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-server/default") + k8s.DeployKustomize(t, members[keyPartition].serverOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-server/partition") + + // Create static client deployments. + k8s.DeployKustomize(t, members[keyPrimaryServer].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-client/default") + k8s.DeployKustomize(t, members[keyPartition].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-client/partition") + + // Verify that both static-server and static-client have been injected and now have 2 containers in server cluster. + // Also get the server IP + for _, labelSelector := range []string{"app=static-server", "app=static-client"} { + podList, err := members[keyPrimaryServer].context.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), + metav1.ListOptions{LabelSelector: labelSelector}) + require.NoError(t, err) + require.Len(t, podList.Items, 1) + require.Len(t, podList.Items[0].Spec.Containers, 2) + if labelSelector == "app=static-server" { + ip := &podList.Items[0].Status.PodIP + require.NotNil(t, ip) + logger.Logf(t, "default-static-server-ip: %s", *ip) + members[keyPrimaryServer].staticServerIP = ip + } + + podList, err = members[keyPartition].context.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), + metav1.ListOptions{LabelSelector: labelSelector}) + require.NoError(t, err) + require.Len(t, podList.Items, 1) + require.Len(t, podList.Items[0].Spec.Containers, 2) + if labelSelector == "app=static-server" { + ip := &podList.Items[0].Status.PodIP + require.NotNil(t, ip) + logger.Logf(t, "partition-static-server-ip: %s", *ip) + members[keyPartition].staticServerIP = ip + } + } + + logger.Log(t, "creating exported services") + applyResources(t, cfg, "../fixtures/cases/sameness/exported-services/default-partition", members[keyPrimaryServer].context.KubectlOptions(t)) + applyResources(t, cfg, "../fixtures/cases/sameness/exported-services/ap1-partition", members[keyPartition].context.KubectlOptions(t)) + + // Setup DNS. + dnsService, err := members[keyPrimaryServer].context.KubernetesClient(t).CoreV1().Services("default").Get(context.Background(), fmt.Sprintf("%s-%s", releaseName, "consul-dns"), metav1.GetOptions{}) + require.NoError(t, err) + dnsIP := dnsService.Spec.ClusterIP + logger.Logf(t, "dnsIP: %s", dnsIP) + + // Setup Prepared Query. + definition := &api.PreparedQueryDefinition{ + Name: "my-query", + Service: api.ServiceQuery{ + Service: "static-server", + SamenessGroup: "mine", + Namespace: staticServerNamespace, + OnlyPassing: false, + }, + } + resp, _, err := members[keyPrimaryServer].client.PreparedQuery().Create(definition, &api.WriteOptions{}) + require.NoError(t, err) + logger.Logf(t, "PQ ID: %s", resp) + + logger.Log(t, "all infrastructure up and running") + logger.Log(t, "verifying failover scenarios") + + const dnsLookup = "static-server.service.ns2.ns.mine.sg.consul" + const dnsPQLookup = "my-query.query.consul" + + // Verify initial server. + serviceFailoverCheck(t, primaryServerClusterName, members[keyPrimaryServer]) + + // Verify initial dns. + dnsFailoverCheck(t, releaseName, dnsIP, dnsLookup, members[keyPrimaryServer], members[keyPrimaryServer]) + + // Verify initial dns with PQ. + dnsFailoverCheck(t, releaseName, dnsIP, dnsPQLookup, members[keyPrimaryServer], members[keyPrimaryServer]) + + // Scale down static-server on the server, will fail over to partition. + k8s.KubectlScale(t, members[keyPrimaryServer].serverOpts, staticServerDeployment, 0) + + // Verify failover to partition. + serviceFailoverCheck(t, partitionClusterName, members[keyPrimaryServer]) + + // Verify dns failover to partition. + dnsFailoverCheck(t, releaseName, dnsIP, dnsLookup, members[keyPrimaryServer], members[keyPartition]) + + // Verify prepared query failover. + dnsFailoverCheck(t, releaseName, dnsIP, dnsPQLookup, members[keyPrimaryServer], members[keyPartition]) + + logger.Log(t, "tests complete") + }) + } +} + +type member struct { + context environment.TestContext + helmCluster *consul.HelmCluster + client *api.Client + hasServer bool + serverOpts *terratestk8s.KubectlOptions + clientOpts *terratestk8s.KubectlOptions + staticServerIP *string +} + +func createNamespaces(t *testing.T, cfg *config.TestConfig, context environment.TestContext) { + logger.Logf(t, "creating namespaces in %s", context.KubectlOptions(t).ContextName) + k8s.RunKubectl(t, context.KubectlOptions(t), "create", "ns", staticServerNamespace) + k8s.RunKubectl(t, context.KubectlOptions(t), "create", "ns", staticClientNamespace) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + k8s.RunKubectl(t, context.KubectlOptions(t), "delete", "ns", staticClientNamespace, staticServerNamespace) + }) +} + +func applyResources(t *testing.T, cfg *config.TestConfig, kustomizeDir string, opts *terratestk8s.KubectlOptions) { + k8s.KubectlApplyK(t, opts, kustomizeDir) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + k8s.KubectlDeleteK(t, opts, kustomizeDir) + }) +} + +// serviceFailoverCheck verifies that the server failed over as expected by checking that curling the `static-server` +// using the `static-client` responds with the expected cluster name. Each static-server responds with a uniquue +// name so that we can verify failover occured as expected. +func serviceFailoverCheck(t *testing.T, expectedClusterName string, server *member) { + retry.Run(t, func(r *retry.R) { + resp, err := k8s.RunKubectlAndGetOutputE(t, server.clientOpts, "exec", "-i", + staticClientDeployment, "-c", "static-client", "--", "curl", "localhost:8080") + require.NoError(r, err) + assert.Contains(r, resp, expectedClusterName) + logger.Log(t, resp) + }) +} + +func dnsFailoverCheck(t *testing.T, releaseName string, dnsIP string, dnsQuery string, server, failover *member) { + retry.Run(t, func(r *retry.R) { + logs, err := k8s.RunKubectlAndGetOutputE(t, server.clientOpts, "exec", "-i", + staticClientDeployment, "-c", "static-client", "--", "dig", fmt.Sprintf("@%s-consul-dns.default", releaseName), dnsQuery) + require.NoError(r, err) + + // When the `dig` request is successful, a section of its response looks like the following: + // + // ;; ANSWER SECTION: + // static-server.service.mine.sg.ns2.ns.consul. 0 IN A + // + // ;; Query time: 2 msec + // ;; SERVER: #() + // ;; WHEN: Mon Aug 10 15:02:40 UTC 2020 + // ;; MSG SIZE rcvd: 98 + // + // We assert on the existence of the ANSWER SECTION, The consul-server IPs being present in + // the ANSWER SECTION and the DNS IP mentioned in the SERVER: field + + assert.Contains(r, logs, fmt.Sprintf("SERVER: %s", dnsIP)) + assert.Contains(r, logs, "ANSWER SECTION:") + assert.Contains(r, logs, *failover.staticServerIP) + }) +} From 89ee905738aca9e1f68aff47676c3bd60d7dc237 Mon Sep 17 00:00:00 2001 From: Ganesh S Date: Fri, 28 Jul 2023 10:02:15 -0700 Subject: [PATCH 096/120] Added logLevel field for components (#2302) * Added logLevel field for components * Add changelog * Fix tests * Rename 2298.txt to 2302.txt * Address comments * Fix tests * Fix helm tests * Address comments * Add client and server loglevels * Fix bats * Update changelog * Fix bats tests --- .changelog/2302.txt | 13 ++++ .../templates/client-config-configmap.yaml | 6 ++ .../create-federation-secret-job.yaml | 2 +- .../gossip-encryption-autogenerate-job.yaml | 2 +- .../ingress-gateways-deployment.yaml | 4 +- .../templates/mesh-gateway-deployment.yaml | 4 +- .../server-acl-init-cleanup-job.yaml | 2 +- .../consul/templates/server-acl-init-job.yaml | 2 +- .../templates/server-config-configmap.yaml | 3 + .../telemetry-collector-deployment.yaml | 4 +- .../terminating-gateways-deployment.yaml | 4 +- charts/consul/templates/tls-init-job.yaml | 2 +- .../test/unit/client-config-configmap.bats | 26 ++++++++ charts/consul/test/unit/client-daemonset.bats | 6 +- .../unit/create-federation-secret-job.bats | 38 ++++++++++++ .../gossip-encryption-autogenerate-job.bats | 30 +++++++++ .../unit/ingress-gateways-deployment.bats | 61 +++++++++++++++++++ .../test/unit/mesh-gateway-deployment.bats | 61 +++++++++++++++++++ .../unit/server-acl-init-cleanup-job.bats | 28 +++++++++ .../consul/test/unit/server-acl-init-job.bats | 30 +++++++++ .../test/unit/server-config-configmap.bats | 21 +++++++ .../unit/telemetry-collector-deployment.bats | 57 +++++++++++++++++ .../unit/terminating-gateways-deployment.bats | 61 +++++++++++++++++++ charts/consul/test/unit/tls-init-job.bats | 30 +++++++++ charts/consul/values.yaml | 39 ++++++++++++ 25 files changed, 520 insertions(+), 16 deletions(-) create mode 100644 .changelog/2302.txt diff --git a/.changelog/2302.txt b/.changelog/2302.txt new file mode 100644 index 0000000000..7bf7e6b0f6 --- /dev/null +++ b/.changelog/2302.txt @@ -0,0 +1,13 @@ +```release-note:improvement +Add support to provide the logLevel flag via helm for multiple low level components. Introduces the following fields +1. `global.acls.logLevel` +2. `global.tls.logLevel` +3. `global.federation.logLevel` +4. `global.gossipEncryption.logLevel` +5. `server.logLevel` +6. `client.logLevel` +7. `meshGateway.logLevel` +8. `ingressGateways.logLevel` +9. `terminatingGateways.logLevel` +10. `telemetryCollector.logLevel` +``` diff --git a/charts/consul/templates/client-config-configmap.yaml b/charts/consul/templates/client-config-configmap.yaml index f9650a100b..d91a4d21bf 100644 --- a/charts/consul/templates/client-config-configmap.yaml +++ b/charts/consul/templates/client-config-configmap.yaml @@ -19,6 +19,12 @@ data: "auto_reload_config": true {{- end }} } + log-level.json: |- + { + {{- if .Values.client.logLevel }} + "log_level": "{{ .Values.client.logLevel | upper }}" + {{- end }} + } extra-from-values.json: |- {{ tpl .Values.client.extraConfig . | trimAll "\"" | indent 4 }} central-config.json: |- diff --git a/charts/consul/templates/create-federation-secret-job.yaml b/charts/consul/templates/create-federation-secret-job.yaml index 4f83a1f82a..bc3e0a988b 100644 --- a/charts/consul/templates/create-federation-secret-job.yaml +++ b/charts/consul/templates/create-federation-secret-job.yaml @@ -119,7 +119,7 @@ spec: - "-ec" - | consul-k8s-control-plane create-federation-secret \ - -log-level={{ .Values.global.logLevel }} \ + -log-level={{ default .Values.global.logLevel .Values.global.federation.logLevel }} \ -log-json={{ .Values.global.logJSON }} \ {{- if (or .Values.global.gossipEncryption.autoGenerate (and .Values.global.gossipEncryption.secretName .Values.global.gossipEncryption.secretKey)) }} -gossip-key-file=/consul/gossip/gossip.key \ diff --git a/charts/consul/templates/gossip-encryption-autogenerate-job.yaml b/charts/consul/templates/gossip-encryption-autogenerate-job.yaml index 240bfe3f9c..02fb3ea168 100644 --- a/charts/consul/templates/gossip-encryption-autogenerate-job.yaml +++ b/charts/consul/templates/gossip-encryption-autogenerate-job.yaml @@ -57,7 +57,7 @@ spec: -namespace={{ .Release.Namespace }} \ -secret-name={{ template "consul.fullname" . }}-gossip-encryption-key \ -secret-key="key" \ - -log-level={{ .Values.global.logLevel }} \ + -log-level={{ default .Values.global.logLevel .Values.global.gossipEncryption.logLevel }} \ -log-json={{ .Values.global.logJSON }} resources: requests: diff --git a/charts/consul/templates/ingress-gateways-deployment.yaml b/charts/consul/templates/ingress-gateways-deployment.yaml index 4f72031855..328c06ee3e 100644 --- a/charts/consul/templates/ingress-gateways-deployment.yaml +++ b/charts/consul/templates/ingress-gateways-deployment.yaml @@ -211,7 +211,7 @@ spec: -gateway-kind="ingress-gateway" \ -proxy-id-file=/consul/service/proxy-id \ -service-name={{ template "consul.fullname" $root }}-{{ .name }} \ - -log-level={{ default $root.Values.global.logLevel }} \ + -log-level={{ default $root.Values.global.logLevel $root.Values.ingressGateways.logLevel }} \ -log-json={{ $root.Values.global.logJSON }} volumeMounts: - name: consul-service @@ -319,7 +319,7 @@ spec: {{- if $root.Values.global.adminPartitions.enabled }} - -service-partition={{ $root.Values.global.adminPartitions.name }} {{- end }} - - -log-level={{ default $root.Values.global.logLevel }} + - -log-level={{ default $root.Values.global.logLevel $root.Values.ingressGateways.logLevel }} - -log-json={{ $root.Values.global.logJSON }} {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} - -telemetry-prom-scrape-path=/metrics diff --git a/charts/consul/templates/mesh-gateway-deployment.yaml b/charts/consul/templates/mesh-gateway-deployment.yaml index 449d6ae492..1936138db3 100644 --- a/charts/consul/templates/mesh-gateway-deployment.yaml +++ b/charts/consul/templates/mesh-gateway-deployment.yaml @@ -161,7 +161,7 @@ spec: -gateway-kind="mesh-gateway" \ -proxy-id-file=/consul/service/proxy-id \ -service-name={{ .Values.meshGateway.consulServiceName }} \ - -log-level={{ default .Values.global.logLevel }} \ + -log-level={{ default .Values.global.logLevel .Values.meshGateway.logLevel }} \ -log-json={{ .Values.global.logJSON }} volumeMounts: - name: consul-service @@ -267,7 +267,7 @@ spec: {{- if .Values.global.adminPartitions.enabled }} - -service-partition={{ .Values.global.adminPartitions.name }} {{- end }} - - -log-level={{ default .Values.global.logLevel }} + - -log-level={{ default .Values.global.logLevel .Values.meshGateway.logLevel }} - -log-json={{ .Values.global.logJSON }} {{- if (and .Values.global.metrics.enabled .Values.global.metrics.enableGatewayMetrics) }} - -telemetry-prom-scrape-path=/metrics diff --git a/charts/consul/templates/server-acl-init-cleanup-job.yaml b/charts/consul/templates/server-acl-init-cleanup-job.yaml index c9f6763bd8..39754d6c6f 100644 --- a/charts/consul/templates/server-acl-init-cleanup-job.yaml +++ b/charts/consul/templates/server-acl-init-cleanup-job.yaml @@ -67,7 +67,7 @@ spec: - consul-k8s-control-plane args: - delete-completed-job - - -log-level={{ .Values.global.logLevel }} + - -log-level={{ default .Values.global.logLevel .Values.global.acls.logLevel }} - -log-json={{ .Values.global.logJSON }} - -k8s-namespace={{ .Release.Namespace }} - {{ template "consul.fullname" . }}-server-acl-init diff --git a/charts/consul/templates/server-acl-init-job.yaml b/charts/consul/templates/server-acl-init-job.yaml index c3d4a710e8..e8a06cf7aa 100644 --- a/charts/consul/templates/server-acl-init-job.yaml +++ b/charts/consul/templates/server-acl-init-job.yaml @@ -171,7 +171,7 @@ spec: CONSUL_FULLNAME="{{template "consul.fullname" . }}" consul-k8s-control-plane server-acl-init \ - -log-level={{ .Values.global.logLevel }} \ + -log-level={{ default .Values.global.logLevel .Values.global.acls.logLevel}} \ -log-json={{ .Values.global.logJSON }} \ -resource-prefix=${CONSUL_FULLNAME} \ -k8s-namespace={{ .Release.Namespace }} \ diff --git a/charts/consul/templates/server-config-configmap.yaml b/charts/consul/templates/server-config-configmap.yaml index 7e3d251001..6c102f0ae3 100644 --- a/charts/consul/templates/server-config-configmap.yaml +++ b/charts/consul/templates/server-config-configmap.yaml @@ -27,6 +27,9 @@ data: }, "datacenter": "{{ .Values.global.datacenter }}", "data_dir": "/consul/data", + {{- if .Values.server.logLevel }} + "log_level": "{{ .Values.server.logLevel | upper }}", + {{- end }} "domain": "{{ .Values.global.domain }}", "limits": { "request_limits": { diff --git a/charts/consul/templates/telemetry-collector-deployment.yaml b/charts/consul/templates/telemetry-collector-deployment.yaml index b729273dd8..4b5bb6df7b 100644 --- a/charts/consul/templates/telemetry-collector-deployment.yaml +++ b/charts/consul/templates/telemetry-collector-deployment.yaml @@ -115,7 +115,7 @@ spec: - -ec - |- consul-k8s-control-plane connect-init -pod-name=${POD_NAME} -pod-namespace=${POD_NAMESPACE} \ - -log-level={{ default .Values.global.logLevel }} \ + -log-level={{ default .Values.global.logLevel .Values.telemetryCollector.logLevel }} \ -log-json={{ .Values.global.logJSON }} \ -service-account-name="consul-telemetry-collector" \ -service-name="" \ @@ -303,7 +303,7 @@ spec: {{- if .Values.global.metrics.enabled }} - -telemetry-prom-scrape-path=/metrics {{- end }} - - -log-level={{ default .Values.global.logLevel }} + - -log-level={{ default .Values.global.logLevel .Values.telemetryCollector.logLevel }} - -log-json={{ .Values.global.logJSON }} - -envoy-concurrency=2 {{- if and .Values.externalServers.enabled .Values.externalServers.skipServerWatch }} diff --git a/charts/consul/templates/terminating-gateways-deployment.yaml b/charts/consul/templates/terminating-gateways-deployment.yaml index 2f2cb9a921..fdf2c17d05 100644 --- a/charts/consul/templates/terminating-gateways-deployment.yaml +++ b/charts/consul/templates/terminating-gateways-deployment.yaml @@ -196,7 +196,7 @@ spec: -gateway-kind="terminating-gateway" \ -proxy-id-file=/consul/service/proxy-id \ -service-name={{ .name }} \ - -log-level={{ default $root.Values.global.logLevel }} \ + -log-level={{ default $root.Values.global.logLevel $root.Values.terminatingGateways.logLevel }} \ -log-json={{ $root.Values.global.logJSON }} volumeMounts: - name: consul-service @@ -300,7 +300,7 @@ spec: {{- if $root.Values.global.adminPartitions.enabled }} - -service-partition={{ $root.Values.global.adminPartitions.name }} {{- end }} - - -log-level={{ default $root.Values.global.logLevel }} + - -log-level={{ default $root.Values.global.logLevel $root.Values.terminatingGateways.logLevel }} - -log-json={{ $root.Values.global.logJSON }} {{- if (and $root.Values.global.metrics.enabled $root.Values.global.metrics.enableGatewayMetrics) }} - -telemetry-prom-scrape-path=/metrics diff --git a/charts/consul/templates/tls-init-job.yaml b/charts/consul/templates/tls-init-job.yaml index 12d3acbad8..47651fe14b 100644 --- a/charts/consul/templates/tls-init-job.yaml +++ b/charts/consul/templates/tls-init-job.yaml @@ -80,7 +80,7 @@ spec: # and use * at the start of the dns name when setting -additional-dnsname. set -o noglob consul-k8s-control-plane tls-init \ - -log-level={{ .Values.global.logLevel }} \ + -log-level={{ default .Values.global.logLevel .Values.global.tls.logLevel }} \ -log-json={{ .Values.global.logJSON }} \ -domain={{ .Values.global.domain }} \ -days=730 \ diff --git a/charts/consul/test/unit/client-config-configmap.bats b/charts/consul/test/unit/client-config-configmap.bats index 5fc4a186d9..1f1443a156 100755 --- a/charts/consul/test/unit/client-config-configmap.bats +++ b/charts/consul/test/unit/client-config-configmap.bats @@ -95,3 +95,29 @@ load _helpers [ "${actual}" = null ] } + +#-------------------------------------------------------------------- +# logLevel + +@test "client/ConfigMap: client.logLevel is empty" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/client-config-configmap.yaml \ + --set 'client.enabled=true' \ + . | tee /dev/stderr | + yq -r '.data["log-level.json"]' | jq -r .log_level | tee /dev/stderr) + + [ "${actual}" = "null" ] +} + +@test "client/ConfigMap: client.logLevel is non empty" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/client-config-configmap.yaml \ + --set 'client.enabled=true' \ + --set 'client.logLevel=DEBUG' \ + . | tee /dev/stderr | + yq -r '.data["log-level.json"]' | jq -r .log_level | tee /dev/stderr) + + [ "${actual}" = "DEBUG" ] +} diff --git a/charts/consul/test/unit/client-daemonset.bats b/charts/consul/test/unit/client-daemonset.bats index 6e7a030cb1..d512ad8ab2 100755 --- a/charts/consul/test/unit/client-daemonset.bats +++ b/charts/consul/test/unit/client-daemonset.bats @@ -621,7 +621,7 @@ load _helpers --set 'client.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.template.metadata.annotations."consul.hashicorp.com/config-checksum"' | tee /dev/stderr) - [ "${actual}" = f9be2829fed80a127e3752e10be32f29c2f9ca0ea548abcf3d4fc2c985cb7201 ] + [ "${actual}" = 4fa9ddc3abc4c79eafccb19e5beef80006b7c9736b867d8873554ca03f42a6b3 ] } @test "client/DaemonSet: config-checksum annotation changes when extraConfig is provided" { @@ -632,7 +632,7 @@ load _helpers --set 'client.extraConfig="{\"hello\": \"world\"}"' \ . | tee /dev/stderr | yq -r '.spec.template.metadata.annotations."consul.hashicorp.com/config-checksum"' | tee /dev/stderr) - [ "${actual}" = e9fb5f0b4ff4e36a89e8ca2dc1aed2072306e0dd6d4cc60b3edf155cf8dbe2e9 ] + [ "${actual}" = 42b99932385e7a0580b134fe36a9bda405aab2e375593326677b9838708f0796 ] } @test "client/DaemonSet: config-checksum annotation changes when connectInject.enabled=true" { @@ -643,7 +643,7 @@ load _helpers --set 'connectInject.enabled=true' \ . | tee /dev/stderr | yq -r '.spec.template.metadata.annotations."consul.hashicorp.com/config-checksum"' | tee /dev/stderr) - [ "${actual}" = f9be2829fed80a127e3752e10be32f29c2f9ca0ea548abcf3d4fc2c985cb7201 ] + [ "${actual}" = 4fa9ddc3abc4c79eafccb19e5beef80006b7c9736b867d8873554ca03f42a6b3 ] } #-------------------------------------------------------------------- diff --git a/charts/consul/test/unit/create-federation-secret-job.bats b/charts/consul/test/unit/create-federation-secret-job.bats index e528f28f0e..872cf2e36c 100644 --- a/charts/consul/test/unit/create-federation-secret-job.bats +++ b/charts/consul/test/unit/create-federation-secret-job.bats @@ -418,3 +418,41 @@ load _helpers [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# logLevel + +@test "createFederationSecret/Job: logLevel is not set by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.federation.createFederationSecret=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "createFederationSecret/Job: override the global.logLevel flag with global.federation.logLevel" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/create-federation-secret-job.yaml \ + --set 'global.federation.enabled=true' \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + --set 'global.tls.enabled=true' \ + --set 'global.federation.createFederationSecret=true' \ + --set 'global.federation.logLevel=debug' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=debug"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/charts/consul/test/unit/gossip-encryption-autogenerate-job.bats b/charts/consul/test/unit/gossip-encryption-autogenerate-job.bats index 662b523bc0..7520696182 100644 --- a/charts/consul/test/unit/gossip-encryption-autogenerate-job.bats +++ b/charts/consul/test/unit/gossip-encryption-autogenerate-job.bats @@ -105,3 +105,33 @@ load _helpers [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# logLevel + +@test "gossipEncryptionAutogenerate/Job: uses the global.logLevel flag by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/gossip-encryption-autogenerate-job.yaml \ + --set 'global.gossipEncryption.autoGenerate=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "gossipEncryptionAutogenerate/Job: overrides the global.logLevel flag when global.gossipEncryption.logLevel is set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/gossip-encryption-autogenerate-job.yaml \ + --set 'global.gossipEncryption.autoGenerate=true' \ + --set 'global.gossipEncryption.logLevel=debug' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=debug"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/charts/consul/test/unit/ingress-gateways-deployment.bats b/charts/consul/test/unit/ingress-gateways-deployment.bats index 8ed76be13a..e8390278a8 100644 --- a/charts/consul/test/unit/ingress-gateways-deployment.bats +++ b/charts/consul/test/unit/ingress-gateways-deployment.bats @@ -1504,3 +1504,64 @@ key2: value2' \ [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# logLevel + +@test "ingressGateways/Deployment: use global.logLevel by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: override global.logLevel when ingressGateways.logLevel is set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'ingressGateways.logLevel=warn' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.initContainers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=warn"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: use global.logLevel by default for dataplane container" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "ingressGateways/Deployment: override global.logLevel when ingressGateways.logLevel is set for dataplane container" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/ingress-gateways-deployment.yaml \ + --set 'ingressGateways.enabled=true' \ + --set 'ingressGateways.logLevel=trace' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=trace"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} \ No newline at end of file diff --git a/charts/consul/test/unit/mesh-gateway-deployment.bats b/charts/consul/test/unit/mesh-gateway-deployment.bats index 588b026d40..d58def05da 100755 --- a/charts/consul/test/unit/mesh-gateway-deployment.bats +++ b/charts/consul/test/unit/mesh-gateway-deployment.bats @@ -1644,3 +1644,64 @@ key2: value2' \ [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# logLevel + +@test "meshGateway/Deployment: use global.logLevel by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: override global.logLevel when meshGateway.logLevel is set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'meshGateway.logLevel=warn' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=warn"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: use global.logLevel by default for dataplane container" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "meshGateway/Deployment: override global.logLevel when meshGateway.logLevel is set for dataplane container" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/mesh-gateway-deployment.yaml \ + --set 'meshGateway.enabled=true' \ + --set 'meshGateway.logLevel=warn' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=warn"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} \ No newline at end of file diff --git a/charts/consul/test/unit/server-acl-init-cleanup-job.bats b/charts/consul/test/unit/server-acl-init-cleanup-job.bats index c886b2ec51..8743ea4a8d 100644 --- a/charts/consul/test/unit/server-acl-init-cleanup-job.bats +++ b/charts/consul/test/unit/server-acl-init-cleanup-job.bats @@ -161,6 +161,34 @@ load _helpers } #-------------------------------------------------------------------- +# logLevel + +@test "serverACLInitCleanup/Job: use global.logLevel by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/server-acl-init-cleanup-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInitCleanup/Job: override global.logLevel when global.acls.logLevel is set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/server-acl-init-cleanup-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.logLevel=debug' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=debug"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} # resources @test "serverACLInitCleanup/Job: resources defined by default" { diff --git a/charts/consul/test/unit/server-acl-init-job.bats b/charts/consul/test/unit/server-acl-init-job.bats index 17c3e63935..1dc55a9551 100644 --- a/charts/consul/test/unit/server-acl-init-job.bats +++ b/charts/consul/test/unit/server-acl-init-job.bats @@ -2219,6 +2219,36 @@ load _helpers [ "${actualTemplateBaz}" = "qux" ] } +#-------------------------------------------------------------------- +# logLevel + +@test "serverACLInit/Job: use global.logLevel by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "serverACLInit/Job: override global.logLevel when global.acls.logLevel is set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/server-acl-init-job.yaml \ + --set 'global.acls.manageSystemACLs=true' \ + --set 'global.acls.logLevel=debug' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=debug"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # resources diff --git a/charts/consul/test/unit/server-config-configmap.bats b/charts/consul/test/unit/server-config-configmap.bats index d55c10dd3a..643caeb0a1 100755 --- a/charts/consul/test/unit/server-config-configmap.bats +++ b/charts/consul/test/unit/server-config-configmap.bats @@ -1196,4 +1196,25 @@ load _helpers local actual=$(echo $object | jq -r .audit.sink.MySink3.type | tee /dev/stderr) [ "${actual}" = "file" ] +} + +@test "server/ConfigMap: server.logLevel is empty" { + cd `chart_dir` + local configmap=$(helm template \ + -s templates/server-config-configmap.yaml \ + . | tee /dev/stderr | + yq -r '.data["server.json"]' | jq -r .log_level | tee /dev/stderr) + + [ "${configmap}" = "null" ] +} + +@test "server/ConfigMap: server.logLevel is non empty" { + cd `chart_dir` + local configmap=$(helm template \ + -s templates/server-config-configmap.yaml \ + --set 'server.logLevel=debug' \ + . | tee /dev/stderr | + yq -r '.data["server.json"]' | jq -r .log_level | tee /dev/stderr) + + [ "${configmap}" = "DEBUG" ] } \ No newline at end of file diff --git a/charts/consul/test/unit/telemetry-collector-deployment.bats b/charts/consul/test/unit/telemetry-collector-deployment.bats index 705447621e..7809039e11 100755 --- a/charts/consul/test/unit/telemetry-collector-deployment.bats +++ b/charts/consul/test/unit/telemetry-collector-deployment.bats @@ -1074,3 +1074,60 @@ MIICFjCCAZsCCQCdwLtdjbzlYzAKBggqhkjOPQQDAjB0MQswCQYDVQQGEwJDQTEL' \ yq -r 'map(select(.name == "foo")) | .[0].value' | tee /dev/stderr) [ "${actual}" = "bar" ] } + +#-------------------------------------------------------------------- +# logLevel + +@test "telemetryCollector/Deployment: use global.logLevel by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/telemetry-collector-deployment.yaml \ + --set 'telemetryCollector.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "telemetryCollector/Deployment: override global.logLevel when telemetryCollector.logLevel is set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/telemetry-collector-deployment.yaml \ + --set 'telemetryCollector.enabled=true' \ + --set 'telemetryCollector.logLevel=warn' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=warn"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "telemetryCollector/Deployment: use global.logLevel by default for dataplane container" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/telemetry-collector-deployment.yaml \ + --set 'telemetryCollector.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[1].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "telemetryCollector/Deployment: override global.logLevel when telemetryCollector.logLevel is set for dataplane container" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/telemetry-collector-deployment.yaml \ + --set 'telemetryCollector.enabled=true' \ + --set 'telemetryCollector.logLevel=debug' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[1].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=debug"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} \ No newline at end of file diff --git a/charts/consul/test/unit/terminating-gateways-deployment.bats b/charts/consul/test/unit/terminating-gateways-deployment.bats index 523138a351..1dc3befbdf 100644 --- a/charts/consul/test/unit/terminating-gateways-deployment.bats +++ b/charts/consul/test/unit/terminating-gateways-deployment.bats @@ -1504,3 +1504,64 @@ key2: value2' \ [ "${actualTemplateFoo}" = "bar" ] [ "${actualTemplateBaz}" = "qux" ] } + +#-------------------------------------------------------------------- +# logLevel + +@test "terminatingGateways/Deployment: use global.logLevel by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Deployment: override global.logLevel when terminatingGateways.logLevel is set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'terminatingGateways.logLevel=debug' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.initContainers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=debug"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Deployment: use global.logLevel by default for dataplane container" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "terminatingGateways/Deployment: override global.logLevel when terminatingGateways.logLevel is set for dataplane container" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/terminating-gateways-deployment.yaml \ + --set 'terminatingGateways.enabled=true' \ + --set 'terminatingGateways.logLevel=debug' \ + --set 'connectInject.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=debug"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} diff --git a/charts/consul/test/unit/tls-init-job.bats b/charts/consul/test/unit/tls-init-job.bats index bf1f84a0a6..f71edc43d5 100644 --- a/charts/consul/test/unit/tls-init-job.bats +++ b/charts/consul/test/unit/tls-init-job.bats @@ -208,6 +208,36 @@ load _helpers [ "${actualTemplateBaz}" = "qux" ] } +#-------------------------------------------------------------------- +# logLevel + +@test "tlsInit/Job: use global.logLevel by default" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=info"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + +@test "tlsInit/Job: override global.logLevel when global.tls.logLevel is set" { + cd `chart_dir` + local cmd=$(helm template \ + -s templates/tls-init-job.yaml \ + --set 'global.tls.enabled=true' \ + --set 'global.tls.logLevel=error' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].command' | tee /dev/stderr) + + local actual=$(echo "$cmd" | + yq 'any(contains("-log-level=error"))' | tee /dev/stderr) + [ "${actual}" = "true" ] +} + #-------------------------------------------------------------------- # server.containerSecurityContext.tlsInit diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 81065d4bb2..d373a240f0 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -289,6 +289,9 @@ global: # The key within the Kubernetes secret or Vault secret key that holds the gossip # encryption key. secretKey: "" + # Override global log verbosity level for gossip-encryption-autogenerate-job pods. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" # A list of addresses of upstream DNS servers that are used to recursively resolve DNS queries. # These values are given as `-recursor` flags to Consul servers and clients. @@ -307,6 +310,10 @@ global: # This setting is required for [Cluster Peering](https://developer.hashicorp.com/consul/docs/connect/cluster-peering/k8s). enabled: false + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # If true, turns on the auto-encrypt feature on clients and servers. # It also switches consul-k8s-control-plane components to retrieve the CA from the servers # via the API. Requires Consul 1.7.1+. @@ -406,6 +413,10 @@ global: # This requires Consul >= 1.4. manageSystemACLs: false + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # A Kubernetes or Vault secret containing the bootstrap token to use for creating policies and # tokens for all Consul and consul-k8s-control-plane components. If `secretName` and `secretKey` # are unset, a default secret name and secret key are used. If the secret is populated, then @@ -578,6 +589,10 @@ global: # @type: string k8sAuthMethodHost: null + # Override global log verbosity level for the create-federation-secret-job pods. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # Configures metrics for Consul service mesh metrics: # Configures the Helm chart’s components @@ -731,6 +746,10 @@ server: # @type: boolean enabled: "-" + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # The name of the Docker image (including any tag) for the containers running # Consul server agents. # @type: string @@ -1368,6 +1387,10 @@ client: # @type: boolean enabled: false + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # The name of the Docker image (including any tag) for the containers # running Consul client agents. # @type: string @@ -2643,6 +2666,10 @@ meshGateway: # Requirements: consul 1.6.0+ if using `global.acls.manageSystemACLs``. enabled: false + # Override global log verbosity level for mesh-gateway-deployment pods. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # Number of replicas for the Deployment. replicas: 1 @@ -2855,6 +2882,10 @@ ingressGateways: # Enable ingress gateway deployment. Requires `connectInject.enabled=true`. enabled: false + # Override global log verbosity level for ingress-gateways-deployment pods. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # Defaults sets default values for all gateway fields. With the exception # of annotations, defining any of these values in the `gateways` list # will override the default values provided here. Annotations will @@ -3021,6 +3052,10 @@ terminatingGateways: # Enable terminating gateway deployment. Requires `connectInject.enabled=true`. enabled: false + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # Defaults sets default values for all gateway fields. With the exception # of annotations, defining any of these values in the `gateways` list # will override the default values provided here. Annotations will @@ -3359,6 +3394,10 @@ telemetryCollector: # @type: boolean enabled: false + # Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + # @type: string + logLevel: "" + # The name of the Docker image (including any tag) for the containers running # the consul-telemetry-collector # @type: string From 3e1f79912fa72634b20ba4f31cdc1bf9c9e92803 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Fri, 28 Jul 2023 13:46:07 -0400 Subject: [PATCH 097/120] Add missing tsccr entries (#2682) --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f79369b440..414c875b26 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -193,7 +193,7 @@ jobs: - name: Test rpm package if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} - uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" + uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 # v3 with: image: registry.access.redhat.com/ubi9/ubi:latest options: -v ${{ github.workspace }}:/work @@ -218,7 +218,7 @@ jobs: - name: Test debian package if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} - uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" + uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 # v3 with: image: ubuntu:latest options: -v ${{ github.workspace }}:/work From 63567cb3eee78eb66a1589c53d919430fb93a027 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Fri, 28 Jul 2023 14:57:33 -0400 Subject: [PATCH 098/120] Use controller-gen 0.8.0 for CRDs (#2684) - Add missing license headers. --- Makefile | 2 +- .../fixtures/bases/openshift/network-attachment.yaml | 3 +++ .../fixtures/bases/sameness/default-ns/sameness.yaml | 3 +++ .../bases/sameness/override-ns/intentions.yaml | 3 +++ .../override-ns/payment-service-resolver.yaml | 3 +++ .../bases/sameness/override-ns/service-defaults.yaml | 3 +++ .../tests/fixtures/bases/sameness/peering/mesh.yaml | 3 +++ acceptance/tests/sameness/sameness_test.go | 3 +++ .../templates/crd-controlplanerequestlimits.yaml | 11 +++++++++-- charts/consul/templates/crd-exportedservices.yaml | 11 +++++++++-- charts/consul/templates/crd-gatewayclassconfigs.yaml | 11 +++++++++-- charts/consul/templates/crd-ingressgateways.yaml | 11 +++++++++-- charts/consul/templates/crd-jwtproviders.yaml | 11 +++++++++-- charts/consul/templates/crd-meshes.yaml | 11 +++++++++-- charts/consul/templates/crd-meshservices.yaml | 11 +++++++++-- charts/consul/templates/crd-peeringacceptors.yaml | 11 +++++++++-- charts/consul/templates/crd-peeringdialers.yaml | 11 +++++++++-- charts/consul/templates/crd-proxydefaults.yaml | 11 +++++++++-- charts/consul/templates/crd-referencegrants.yaml | 6 +++--- charts/consul/templates/crd-samenessgroups.yaml | 11 +++++++++-- charts/consul/templates/crd-servicedefaults.yaml | 11 +++++++++-- charts/consul/templates/crd-serviceintentions.yaml | 11 +++++++++-- charts/consul/templates/crd-serviceresolvers.yaml | 11 +++++++++-- charts/consul/templates/crd-servicerouters.yaml | 11 +++++++++-- charts/consul/templates/crd-servicesplitters.yaml | 11 +++++++++-- charts/consul/templates/crd-terminatinggateways.yaml | 11 +++++++++-- ...onsul.hashicorp.com_controlplanerequestlimits.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_exportedservices.yaml | 9 ++++++++- .../consul.hashicorp.com_gatewayclassconfigs.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_ingressgateways.yaml | 9 ++++++++- .../crd/bases/consul.hashicorp.com_jwtproviders.yaml | 9 ++++++++- .../config/crd/bases/consul.hashicorp.com_meshes.yaml | 9 ++++++++- .../crd/bases/consul.hashicorp.com_meshservices.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_peeringacceptors.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_peeringdialers.yaml | 9 ++++++++- .../crd/bases/consul.hashicorp.com_proxydefaults.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_samenessgroups.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_servicedefaults.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_serviceintentions.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_serviceresolvers.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_servicerouters.yaml | 9 ++++++++- .../bases/consul.hashicorp.com_servicesplitters.yaml | 9 ++++++++- .../consul.hashicorp.com_terminatinggateways.yaml | 9 ++++++++- control-plane/config/rbac/role.yaml | 4 ++++ control-plane/config/webhook/manifests.yaml | 4 ++++ 45 files changed, 322 insertions(+), 55 deletions(-) diff --git a/Makefile b/Makefile index e2c39de2ea..a141fa22cd 100644 --- a/Makefile +++ b/Makefile @@ -172,7 +172,7 @@ ifeq (, $(shell which controller-gen)) CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ cd $$CONTROLLER_GEN_TMP_DIR ;\ go mod init tmp ;\ - go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.12.0 ;\ + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0 ;\ rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ } CONTROLLER_GEN=$(shell go env GOPATH)/bin/controller-gen diff --git a/acceptance/tests/fixtures/bases/openshift/network-attachment.yaml b/acceptance/tests/fixtures/bases/openshift/network-attachment.yaml index 4b3f7948ee..c2f36c5e1a 100644 --- a/acceptance/tests/fixtures/bases/openshift/network-attachment.yaml +++ b/acceptance/tests/fixtures/bases/openshift/network-attachment.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: "k8s.cni.cncf.io/v1" kind: NetworkAttachmentDefinition metadata: diff --git a/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml b/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml index 0eb7d9e008..4d27ed72ae 100644 --- a/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml +++ b/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: SamenessGroup metadata: diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml index 425b9fe21d..ae075c85e4 100644 --- a/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceIntentions metadata: diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml index b2b6b68c3d..4257294c6b 100644 --- a/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceResolver metadata: diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml index f88d143728..87f6a71f32 100644 --- a/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceDefaults metadata: diff --git a/acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml b/acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml index de84382d3e..2fb6a04bb6 100644 --- a/acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml +++ b/acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml @@ -1,3 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + apiVersion: consul.hashicorp.com/v1alpha1 kind: Mesh metadata: diff --git a/acceptance/tests/sameness/sameness_test.go b/acceptance/tests/sameness/sameness_test.go index a7a926cd42..3971ccf27a 100644 --- a/acceptance/tests/sameness/sameness_test.go +++ b/acceptance/tests/sameness/sameness_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package sameness import ( diff --git a/charts/consul/templates/crd-controlplanerequestlimits.yaml b/charts/consul/templates/crd-controlplanerequestlimits.yaml index 67ff258eb8..2b0c45a621 100644 --- a/charts/consul/templates/crd-controlplanerequestlimits.yaml +++ b/charts/consul/templates/crd-controlplanerequestlimits.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: controlplanerequestlimits.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: ControlPlaneRequestLimit @@ -193,4 +194,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-exportedservices.yaml b/charts/consul/templates/crd-exportedservices.yaml index 8581ac4e88..591500cb12 100644 --- a/charts/consul/templates/crd-exportedservices.yaml +++ b/charts/consul/templates/crd-exportedservices.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: exportedservices.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: ExportedServices @@ -137,4 +138,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-gatewayclassconfigs.yaml b/charts/consul/templates/crd-gatewayclassconfigs.yaml index 7060757b23..4ab6570e31 100644 --- a/charts/consul/templates/crd-gatewayclassconfigs.yaml +++ b/charts/consul/templates/crd-gatewayclassconfigs.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: gatewayclassconfigs.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: GatewayClassConfig @@ -141,4 +142,10 @@ spec: type: object served: true storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-ingressgateways.yaml b/charts/consul/templates/crd-ingressgateways.yaml index eff7ef61a9..a01fafd8dd 100644 --- a/charts/consul/templates/crd-ingressgateways.yaml +++ b/charts/consul/templates/crd-ingressgateways.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: ingressgateways.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: IngressGateway @@ -367,4 +368,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-jwtproviders.yaml b/charts/consul/templates/crd-jwtproviders.yaml index fa87f37489..8a51d16b68 100644 --- a/charts/consul/templates/crd-jwtproviders.yaml +++ b/charts/consul/templates/crd-jwtproviders.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: jwtproviders.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: JWTProvider @@ -255,4 +256,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-meshes.yaml b/charts/consul/templates/crd-meshes.yaml index f2549b5111..0710d41280 100644 --- a/charts/consul/templates/crd-meshes.yaml +++ b/charts/consul/templates/crd-meshes.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: meshes.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: Mesh @@ -205,4 +206,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-meshservices.yaml b/charts/consul/templates/crd-meshservices.yaml index aa808113a2..df8f673bdc 100644 --- a/charts/consul/templates/crd-meshservices.yaml +++ b/charts/consul/templates/crd-meshservices.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: meshservices.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: MeshService @@ -54,4 +55,10 @@ spec: type: object served: true storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-peeringacceptors.yaml b/charts/consul/templates/crd-peeringacceptors.yaml index 40f7f1d4d6..e06e830f04 100644 --- a/charts/consul/templates/crd-peeringacceptors.yaml +++ b/charts/consul/templates/crd-peeringacceptors.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: peeringacceptors.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: PeeringAcceptor @@ -144,4 +145,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-peeringdialers.yaml b/charts/consul/templates/crd-peeringdialers.yaml index bfe4778d0c..e24401e761 100644 --- a/charts/consul/templates/crd-peeringdialers.yaml +++ b/charts/consul/templates/crd-peeringdialers.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: peeringdialers.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: PeeringDialer @@ -144,4 +145,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-proxydefaults.yaml b/charts/consul/templates/crd-proxydefaults.yaml index a224effc12..362672c1c1 100644 --- a/charts/consul/templates/crd-proxydefaults.yaml +++ b/charts/consul/templates/crd-proxydefaults.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: proxydefaults.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: ProxyDefaults @@ -253,4 +254,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-referencegrants.yaml b/charts/consul/templates/crd-referencegrants.yaml index d50211291d..6ae177d987 100644 --- a/charts/consul/templates/crd-referencegrants.yaml +++ b/charts/consul/templates/crd-referencegrants.yaml @@ -7,15 +7,15 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 - gateway.networking.k8s.io/bundle-version: v0.6.2 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null name: referencegrants.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io diff --git a/charts/consul/templates/crd-samenessgroups.yaml b/charts/consul/templates/crd-samenessgroups.yaml index 7cc3b71ae1..60beb5662c 100644 --- a/charts/consul/templates/crd-samenessgroups.yaml +++ b/charts/consul/templates/crd-samenessgroups.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: samenessgroups.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: SamenessGroup @@ -127,4 +128,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-servicedefaults.yaml b/charts/consul/templates/crd-servicedefaults.yaml index e295732bfa..870f5ad86c 100644 --- a/charts/consul/templates/crd-servicedefaults.yaml +++ b/charts/consul/templates/crd-servicedefaults.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: servicedefaults.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: ServiceDefaults @@ -493,4 +494,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-serviceintentions.yaml b/charts/consul/templates/crd-serviceintentions.yaml index 5f849f65ba..c4d2b5f20d 100644 --- a/charts/consul/templates/crd-serviceintentions.yaml +++ b/charts/consul/templates/crd-serviceintentions.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: serviceintentions.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: ServiceIntentions @@ -309,4 +310,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-serviceresolvers.yaml b/charts/consul/templates/crd-serviceresolvers.yaml index a18cc94de4..eb5643fe49 100644 --- a/charts/consul/templates/crd-serviceresolvers.yaml +++ b/charts/consul/templates/crd-serviceresolvers.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: serviceresolvers.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: ServiceResolver @@ -346,4 +347,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-servicerouters.yaml b/charts/consul/templates/crd-servicerouters.yaml index c5ba99466c..f28da9e7c1 100644 --- a/charts/consul/templates/crd-servicerouters.yaml +++ b/charts/consul/templates/crd-servicerouters.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: servicerouters.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: ServiceRouter @@ -310,4 +311,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-servicesplitters.yaml b/charts/consul/templates/crd-servicesplitters.yaml index abe3ac85cc..a2af050c3d 100644 --- a/charts/consul/templates/crd-servicesplitters.yaml +++ b/charts/consul/templates/crd-servicesplitters.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: servicesplitters.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: ServiceSplitter @@ -184,4 +185,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/charts/consul/templates/crd-terminatinggateways.yaml b/charts/consul/templates/crd-terminatinggateways.yaml index cd58d1679c..583c218be8 100644 --- a/charts/consul/templates/crd-terminatinggateways.yaml +++ b/charts/consul/templates/crd-terminatinggateways.yaml @@ -4,15 +4,16 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: terminatinggateways.consul.hashicorp.com -spec: labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd +spec: group: consul.hashicorp.com names: kind: TerminatingGateway @@ -135,4 +136,10 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] {{- end }} diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_controlplanerequestlimits.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_controlplanerequestlimits.yaml index 4d1d808428..11da54e9ac 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_controlplanerequestlimits.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_controlplanerequestlimits.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: controlplanerequestlimits.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -189,3 +190,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml index dac72f3646..0b6b969856 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_exportedservices.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: exportedservices.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -133,3 +134,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_gatewayclassconfigs.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_gatewayclassconfigs.yaml index 44eff52492..e60e4a1cfa 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_gatewayclassconfigs.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_gatewayclassconfigs.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: gatewayclassconfigs.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -137,3 +138,9 @@ spec: type: object served: true storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_ingressgateways.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_ingressgateways.yaml index e9cf081721..fd8ebc86ff 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_ingressgateways.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_ingressgateways.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: ingressgateways.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -363,3 +364,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_jwtproviders.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_jwtproviders.yaml index 7506cc57dc..2e8ac24330 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_jwtproviders.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_jwtproviders.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: jwtproviders.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -251,3 +252,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_meshes.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_meshes.yaml index 16dd398f99..adbb12bba6 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_meshes.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_meshes.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: meshes.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -201,3 +202,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_meshservices.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_meshservices.yaml index 125883bdc5..04f8f493e7 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_meshservices.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_meshservices.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: meshservices.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -50,3 +51,9 @@ spec: type: object served: true storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_peeringacceptors.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_peeringacceptors.yaml index 894228a218..50df179f04 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_peeringacceptors.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_peeringacceptors.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: peeringacceptors.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -140,3 +141,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_peeringdialers.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_peeringdialers.yaml index 51c3e38319..01e4363f14 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_peeringdialers.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_peeringdialers.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: peeringdialers.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -140,3 +141,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_proxydefaults.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_proxydefaults.yaml index 1be3b37703..7084980bf0 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_proxydefaults.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_proxydefaults.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: proxydefaults.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -249,3 +250,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_samenessgroups.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_samenessgroups.yaml index 259ca7b910..c71a211f63 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_samenessgroups.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_samenessgroups.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: samenessgroups.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -123,3 +124,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_servicedefaults.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_servicedefaults.yaml index 83503f11f3..5a2c7a58fd 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_servicedefaults.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_servicedefaults.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: servicedefaults.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -489,3 +490,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_serviceintentions.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_serviceintentions.yaml index 9553c73450..a4efd6e958 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_serviceintentions.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_serviceintentions.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: serviceintentions.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -305,3 +306,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml index b83a859dc4..0146eca982 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: serviceresolvers.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -342,3 +343,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml index 04590cc007..31f5ee2924 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_servicerouters.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: servicerouters.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -306,3 +307,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml index 3a47472ba7..aa2b592c94 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_servicesplitters.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: servicesplitters.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -180,3 +181,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_terminatinggateways.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_terminatinggateways.yaml index acf61cde4c..b465cd9494 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_terminatinggateways.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_terminatinggateways.yaml @@ -6,7 +6,8 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.12.0 + controller-gen.kubebuilder.io/version: v0.8.0 + creationTimestamp: null name: terminatinggateways.consul.hashicorp.com spec: group: consul.hashicorp.com @@ -131,3 +132,9 @@ spec: storage: true subresources: status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/control-plane/config/rbac/role.yaml b/control-plane/config/rbac/role.yaml index 74328a8ae3..7f90780e02 100644 --- a/control-plane/config/rbac/role.yaml +++ b/control-plane/config/rbac/role.yaml @@ -1,7 +1,11 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: + creationTimestamp: null name: manager-role rules: - apiGroups: diff --git a/control-plane/config/webhook/manifests.yaml b/control-plane/config/webhook/manifests.yaml index a515888527..0861f9253a 100644 --- a/control-plane/config/webhook/manifests.yaml +++ b/control-plane/config/webhook/manifests.yaml @@ -1,7 +1,11 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + --- apiVersion: admissionregistration.k8s.io/v1 kind: MutatingWebhookConfiguration metadata: + creationTimestamp: null name: mutating-webhook-configuration webhooks: - admissionReviewVersions: From 3cb0cce4f21dcc6111355b092ba1c22984576243 Mon Sep 17 00:00:00 2001 From: Ashwin Venkatesh Date: Fri, 28 Jul 2023 16:08:17 -0400 Subject: [PATCH 099/120] Fix ingress (#2687) --- .changelog/2687.txt | 3 +++ charts/consul/templates/ui-ingress.yaml | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 .changelog/2687.txt diff --git a/.changelog/2687.txt b/.changelog/2687.txt new file mode 100644 index 0000000000..5fa4a92b4d --- /dev/null +++ b/.changelog/2687.txt @@ -0,0 +1,3 @@ +```release-note:bug +helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. +``` \ No newline at end of file diff --git a/charts/consul/templates/ui-ingress.yaml b/charts/consul/templates/ui-ingress.yaml index 0414a7cc2d..f8c7f92a77 100644 --- a/charts/consul/templates/ui-ingress.yaml +++ b/charts/consul/templates/ui-ingress.yaml @@ -25,9 +25,11 @@ metadata: {{ tpl .Values.ui.ingress.annotations . | nindent 4 | trim }} {{- end }} spec: + {{- if ne .Values.ui.ingress.ingressClassName "" }} ingressClassName: {{ .Values.ui.ingress.ingressClassName }} + {{- end }} rules: - {{ $global := .Values.global }} + {{- $global := .Values.global }} {{- if or ( gt .Capabilities.KubeVersion.Major "1" ) ( ge .Capabilities.KubeVersion.Minor "19" ) }} {{- range .Values.ui.ingress.hosts }} - host: {{ .host | quote }} From 6835b1ef5367752d245981b2af15873f50a3ecae Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Fri, 28 Jul 2023 16:36:50 -0400 Subject: [PATCH 100/120] [NET-4865] Bump golang.org/x/net to 0.12.0 in cni (#2668) * Bump golang.org/x/net to 0.12.0 in cni This was missed in 5b57e6340dff44157cb7a984ac7220e47849dfb9 as part of a general upgrade of that dependency. * Bump server-connection-manager to v0.1.3 Tidying up following CVE dependency bumps, leading to a new release of this library. --- control-plane/cni/go.mod | 8 ++++---- control-plane/cni/go.sum | 16 ++++++++-------- control-plane/go.mod | 2 +- control-plane/go.sum | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/control-plane/cni/go.mod b/control-plane/cni/go.mod index b594015392..fe67475524 100644 --- a/control-plane/cni/go.mod +++ b/control-plane/cni/go.mod @@ -30,11 +30,11 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/net v0.7.0 // indirect + golang.org/x/net v0.12.0 // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/term v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/protobuf v1.27.1 // indirect diff --git a/control-plane/cni/go.sum b/control-plane/cni/go.sum index 845baf6231..f95d4d991a 100644 --- a/control-plane/cni/go.sum +++ b/control-plane/cni/go.sum @@ -287,8 +287,8 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -339,21 +339,21 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/control-plane/go.mod b/control-plane/go.mod index 9d184840cb..8469502795 100644 --- a/control-plane/go.mod +++ b/control-plane/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/go-cmp v0.5.9 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/hashicorp/consul-k8s/control-plane/cni v0.0.0-20230511143918-bd16ab83383d - github.com/hashicorp/consul-server-connection-manager v0.1.2 + github.com/hashicorp/consul-server-connection-manager v0.1.3 github.com/hashicorp/consul/api v1.22.0-rc1 github.com/hashicorp/consul/sdk v0.14.0-rc1 github.com/hashicorp/go-bexpr v0.1.11 diff --git a/control-plane/go.sum b/control-plane/go.sum index fa88dab62a..39e89efec8 100644 --- a/control-plane/go.sum +++ b/control-plane/go.sum @@ -262,8 +262,8 @@ github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEo github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul-k8s/control-plane/cni v0.0.0-20230511143918-bd16ab83383d h1:RJ1MZ8JKnfgKQ1kR3IBQAMpOpzXrdseZAYN/QR//MFM= github.com/hashicorp/consul-k8s/control-plane/cni v0.0.0-20230511143918-bd16ab83383d/go.mod h1:IHIHMzkoMwlv6rLsgwcoFBVYupR7/1pKEOHBMjD4L0k= -github.com/hashicorp/consul-server-connection-manager v0.1.2 h1:tNVQHUPuMbd+cMdD8kd+qkZUYpmLmrHMAV/49f4L53I= -github.com/hashicorp/consul-server-connection-manager v0.1.2/go.mod h1:NzQoVi1KcxGI2SangsDue8+ZPuXZWs+6BKAKrDNyg+w= +github.com/hashicorp/consul-server-connection-manager v0.1.3 h1:fxsZ15XBNNWhV26yBVdCcnxHwSRgf9wqHGS2ZVCQIhc= +github.com/hashicorp/consul-server-connection-manager v0.1.3/go.mod h1:Md2IGKaFJ4ek9GUA0pW1S2R60wpquMOUs27GiD9kZd0= github.com/hashicorp/consul/api v1.22.0-rc1 h1:ePmGqndeMgaI38KUbSA/CqTzeEAIogXyWnfNJzglo70= github.com/hashicorp/consul/api v1.22.0-rc1/go.mod h1:wtduXtbAqSGtBdi3tyA5SSAYGAG51rBejV9SEUBciMY= github.com/hashicorp/consul/proto-public v0.1.0 h1:O0LSmCqydZi363hsqc6n2v5sMz3usQMXZF6ziK3SzXU= From da99ce404f3f35f87dd51ace4fb11f68097fdfc8 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Mon, 31 Jul 2023 09:55:04 -0400 Subject: [PATCH 101/120] Fix default Ent image tag in acceptance tests (#2683) * Fix default Ent image tag in acceptance tests Rather than hard-coding the Docker repository and parsing the non-Ent image tag for a version, simply replace the image name and retain other coordinates. This is consistent with our tagging scheme introduced in https://github.com/hashicorp/consul/pull/13541 and will allow for using `hashicorppreview` images seamlessly regardless of whether OSS or Ent is being tested. * Add make target for loading images in kind Complement other multi-cluster make targets by supporting image loading across kind clusters. --- Makefile | 7 ++++++ acceptance/framework/config/config.go | 21 ++++++---------- acceptance/framework/config/config_test.go | 29 ++++++++++++++-------- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index a141fa22cd..e9a02a01b3 100644 --- a/Makefile +++ b/Makefile @@ -151,6 +151,13 @@ kind: kind-delete kind create cluster --name dc3 --image $(KIND_NODE_IMAGE) kind create cluster --name dc4 --image $(KIND_NODE_IMAGE) +# Helper target for loading local dev images (run with `DEV_IMAGE=...` to load non-k8s images) +kind-load: + kind load docker-image --name dc1 $(DEV_IMAGE) + kind load docker-image --name dc2 $(DEV_IMAGE) + kind load docker-image --name dc3 $(DEV_IMAGE) + kind load docker-image --name dc4 $(DEV_IMAGE) + # ===========> Shared Targets help: ## Show targets and their descriptions. diff --git a/acceptance/framework/config/config.go b/acceptance/framework/config/config.go index ee07df63fd..a638732c37 100644 --- a/acceptance/framework/config/config.go +++ b/acceptance/framework/config/config.go @@ -217,21 +217,16 @@ func (t *TestConfig) entImage() (string, error) { } // Otherwise, assume that we have an image tag with a version in it. - consulImageSplits := strings.Split(v.Global.Image, ":") - if len(consulImageSplits) != 2 { - return "", fmt.Errorf("could not determine consul version from global.image: %s", v.Global.Image) - } - consulImageVersion := consulImageSplits[1] - - var preRelease string - // Handle versions like 1.9.0-rc1. - if strings.Contains(consulImageVersion, "-") { - split := strings.Split(consulImageVersion, "-") - consulImageVersion = split[0] - preRelease = fmt.Sprintf("-%s", split[1]) + // Use the same Docker repository and tagging scheme, but replace 'consul' with 'consul-enterprise'. + imageTag := strings.Replace(v.Global.Image, "/consul:", "/consul-enterprise:", 1) + + // We currently add an '-ent' suffix to release versions of enterprise images (nightly previews + // do not include this suffix). + if strings.HasPrefix(imageTag, "hashicorp/consul-enterprise:") { + imageTag = fmt.Sprintf("%s-ent", imageTag) } - return fmt.Sprintf("hashicorp/consul-enterprise:%s%s-ent", consulImageVersion, preRelease), nil + return imageTag, nil } func (c *TestConfig) SkipWhenOpenshiftAndCNI(t *testing.T) { diff --git a/acceptance/framework/config/config_test.go b/acceptance/framework/config/config_test.go index df981e26fa..4d432da3b0 100644 --- a/acceptance/framework/config/config_test.go +++ b/acceptance/framework/config/config_test.go @@ -137,25 +137,34 @@ func TestConfig_HelmValuesFromConfig_EntImage(t *testing.T) { expErr string }{ { - consulImage: "hashicorp/consul:1.9.0", - expImage: "hashicorp/consul-enterprise:1.9.0-ent", + consulImage: "hashicorp/consul:1.15.3", + expImage: "hashicorp/consul-enterprise:1.15.3-ent", }, { - consulImage: "hashicorp/consul:1.8.5-rc1", - expImage: "hashicorp/consul-enterprise:1.8.5-rc1-ent", + consulImage: "hashicorp/consul:1.16.0-rc1", + expImage: "hashicorp/consul-enterprise:1.16.0-rc1-ent", }, { - consulImage: "hashicorp/consul:1.7.0-beta3", - expImage: "hashicorp/consul-enterprise:1.7.0-beta3-ent", - }, - { - consulImage: "invalid", - expErr: "could not determine consul version from global.image: invalid", + consulImage: "hashicorp/consul:1.14.0-beta1", + expImage: "hashicorp/consul-enterprise:1.14.0-beta1-ent", }, { consulImage: "hashicorp/consul@sha256:oioi2452345kjhlkh", expImage: "hashicorp/consul@sha256:oioi2452345kjhlkh", }, + // Nightly tags differ from release tags ('-ent' suffix is omitted) + { + consulImage: "docker.mirror.hashicorp.services/hashicorppreview/consul:1.17-dev", + expImage: "docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.17-dev", + }, + { + consulImage: "docker.mirror.hashicorp.services/hashicorppreview/consul:1.17-dev-ubi", + expImage: "docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.17-dev-ubi", + }, + { + consulImage: "docker.mirror.hashicorp.services/hashicorppreview/consul@sha256:oioi2452345kjhlkh", + expImage: "docker.mirror.hashicorp.services/hashicorppreview/consul@sha256:oioi2452345kjhlkh", + }, } for _, tt := range tests { t.Run(tt.consulImage, func(t *testing.T) { From 8379be90d833aee74ec2ffc21f6068bab006fb41 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Wed, 2 Aug 2023 13:04:28 -0400 Subject: [PATCH 102/120] [NET-5146] security: Upgrade Go and `x/net` (#2710) security: Upgrade Go and x/net Upgrade to Go 1.20.7 and `x/net` 1.13.0 to resolve [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409) and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978). --- .changelog/2710.txt | 5 +++++ .go-version | 2 +- acceptance/go.mod | 2 +- acceptance/go.sum | 4 ++-- cli/go.mod | 2 +- cli/go.sum | 4 ++-- control-plane/cni/go.mod | 2 +- control-plane/cni/go.sum | 4 ++-- control-plane/go.mod | 2 +- control-plane/go.sum | 4 ++-- 10 files changed, 18 insertions(+), 13 deletions(-) create mode 100644 .changelog/2710.txt diff --git a/.changelog/2710.txt b/.changelog/2710.txt new file mode 100644 index 0000000000..1d37b32dfb --- /dev/null +++ b/.changelog/2710.txt @@ -0,0 +1,5 @@ +```release-note:security +Upgrade to use Go 1.20.7 and `x/net` 0.13.0. +This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) +and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). +``` diff --git a/.go-version b/.go-version index e63679c766..8909929f6e 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.20.6 +1.20.7 diff --git a/acceptance/go.mod b/acceptance/go.mod index b19015eda4..1dd344a5c8 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -122,7 +122,7 @@ require ( golang.org/x/crypto v0.11.0 // indirect golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.12.0 // indirect + golang.org/x/net v0.13.0 // indirect golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/term v0.10.0 // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index 43a557f32b..7361efbbb6 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -887,8 +887,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= diff --git a/cli/go.mod b/cli/go.mod index 5744e9dad0..3e92113d18 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -168,7 +168,7 @@ require ( go.starlark.net v0.0.0-20230128213706-3f75dec8e403 // indirect golang.org/x/crypto v0.11.0 // indirect golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/net v0.12.0 // indirect + golang.org/x/net v0.13.0 // indirect golang.org/x/oauth2 v0.6.0 // indirect golang.org/x/sync v0.2.0 // indirect golang.org/x/sys v0.10.0 // indirect diff --git a/cli/go.sum b/cli/go.sum index 7861cb73d3..6b54e646b2 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -963,8 +963,8 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= diff --git a/control-plane/cni/go.mod b/control-plane/cni/go.mod index fe67475524..e8fcc980ef 100644 --- a/control-plane/cni/go.mod +++ b/control-plane/cni/go.mod @@ -30,7 +30,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - golang.org/x/net v0.12.0 // indirect + golang.org/x/net v0.13.0 // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/term v0.10.0 // indirect diff --git a/control-plane/cni/go.sum b/control-plane/cni/go.sum index f95d4d991a..8f4c0668ea 100644 --- a/control-plane/cni/go.sum +++ b/control-plane/cni/go.sum @@ -287,8 +287,8 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= diff --git a/control-plane/go.mod b/control-plane/go.mod index 8469502795..2dcd78848c 100644 --- a/control-plane/go.mod +++ b/control-plane/go.mod @@ -145,7 +145,7 @@ require ( go.uber.org/multierr v1.6.0 // indirect golang.org/x/crypto v0.11.0 // indirect golang.org/x/mod v0.9.0 // indirect - golang.org/x/net v0.12.0 // indirect + golang.org/x/net v0.13.0 // indirect golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/sync v0.2.0 // indirect golang.org/x/sys v0.10.0 // indirect diff --git a/control-plane/go.sum b/control-plane/go.sum index 39e89efec8..dec3ba9eb4 100644 --- a/control-plane/go.sum +++ b/control-plane/go.sum @@ -655,8 +655,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50= -golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= From 61c77616d390b9077b9bbfa7b9d0f80bae847571 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Wed, 2 Aug 2023 16:07:27 -0400 Subject: [PATCH 103/120] Increase timeout while waiting for vault server to be ready (#2709) increase timeout while waiting for server to be ready and fix require.Equal check --- acceptance/framework/vault/vault_cluster.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index 4dc832bcb6..8b82e41841 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -414,12 +414,12 @@ func (v *VaultCluster) initAndUnseal(t *testing.T) { v.logger.Logf(t, "initializing and unsealing Vault") namespace := v.helmOptions.KubectlOptions.Namespace - retrier := &retry.Timer{Timeout: 2 * time.Minute, Wait: 1 * time.Second} + retrier := &retry.Timer{Timeout: 4 * time.Minute, Wait: 1 * time.Second} retry.RunWith(retrier, t, func(r *retry.R) { // Wait for vault server pod to be running so that we can create Vault client without errors. serverPod, err := v.kubernetesClient.CoreV1().Pods(namespace).Get(context.Background(), fmt.Sprintf("%s-vault-0", v.releaseName), metav1.GetOptions{}) require.NoError(r, err) - require.Equal(r, serverPod.Status.Phase, corev1.PodRunning) + require.Equal(r, corev1.PodRunning, serverPod.Status.Phase) // Set up the client so that we can make API calls to initialize and unseal. v.vaultClient = v.SetupVaultClient(t) From 939e7c31993b0f3c83feceea79ae6c2e3064f700 Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Thu, 3 Aug 2023 16:43:08 -0400 Subject: [PATCH 104/120] Acceptance tests: increase api-gateway retries (#2716) * Increase the retries and add config entry retries --- .../api_gateway_external_servers_test.go | 2 +- .../api-gateway/api_gateway_lifecycle_test.go | 14 ++++---- .../api-gateway/api_gateway_tenancy_test.go | 6 ++-- .../tests/api-gateway/api_gateway_test.go | 35 +++++++++++-------- .../partitions/partitions_gateway_test.go | 21 +++++++++++ 5 files changed, 52 insertions(+), 26 deletions(-) diff --git a/acceptance/tests/api-gateway/api_gateway_external_servers_test.go b/acceptance/tests/api-gateway/api_gateway_external_servers_test.go index d14ef59990..aa0934dc65 100644 --- a/acceptance/tests/api-gateway/api_gateway_external_servers_test.go +++ b/acceptance/tests/api-gateway/api_gateway_external_servers_test.go @@ -96,7 +96,7 @@ func TestAPIGateway_ExternalServers(t *testing.T) { // leader election so we may need to wait a long time for // the reconcile loop to run (hence a ~1m timeout here). var gatewayAddress string - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { var gateway gwv1beta1.Gateway err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: "default"}, &gateway) require.NoError(r, err) diff --git a/acceptance/tests/api-gateway/api_gateway_lifecycle_test.go b/acceptance/tests/api-gateway/api_gateway_lifecycle_test.go index e3ffa992ce..f6f66ed995 100644 --- a/acceptance/tests/api-gateway/api_gateway_lifecycle_test.go +++ b/acceptance/tests/api-gateway/api_gateway_lifecycle_test.go @@ -196,7 +196,7 @@ func TestAPIGateway_Lifecycle(t *testing.T) { // check that the route is unbound and all Consul objects and Kubernetes statuses are cleaned up logger.Log(t, "checking that http route one is not bound to gateway two") - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { var route gwv1beta1.HTTPRoute err := k8sClient.Get(context.Background(), types.NamespacedName{Name: routeOneName, Namespace: defaultNamespace}, &route) require.NoError(r, err) @@ -246,7 +246,7 @@ func TestAPIGateway_Lifecycle(t *testing.T) { // check that the Kubernetes gateway is cleaned up logger.Log(t, "checking that gateway one is cleaned up in Kubernetes") - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { var route gwv1beta1.Gateway err := k8sClient.Get(context.Background(), types.NamespacedName{Name: controlledGatewayOneName, Namespace: defaultNamespace}, &route) require.NoError(r, err) @@ -299,7 +299,7 @@ func checkConsulNotExists(t *testing.T, client *api.Client, kind, name string, n opts.Namespace = namespace[0] } - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { _, _, err := client.ConfigEntries().Get(kind, name, opts) require.Error(r, err) require.EqualError(r, err, fmt.Sprintf("Unexpected response code: 404 (Config entry not found for %q / %q)", kind, name)) @@ -309,7 +309,7 @@ func checkConsulNotExists(t *testing.T, client *api.Client, kind, name string, n func checkConsulExists(t *testing.T, client *api.Client, kind, name string) { t.Helper() - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { _, _, err := client.ConfigEntries().Get(kind, name, nil) require.NoError(r, err) }) @@ -318,7 +318,7 @@ func checkConsulExists(t *testing.T, client *api.Client, kind, name string) { func checkConsulRouteParent(t *testing.T, client *api.Client, name, parent string) { t.Helper() - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { entry, _, err := client.ConfigEntries().Get(api.HTTPRoute, name, nil) require.NoError(r, err) route := entry.(*api.HTTPRouteConfigEntry) @@ -331,7 +331,7 @@ func checkConsulRouteParent(t *testing.T, client *api.Client, name, parent strin func checkEmptyRoute(t *testing.T, client client.Client, name, namespace string) { t.Helper() - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { var route gwv1beta1.HTTPRoute err := client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, &route) require.NoError(r, err) @@ -344,7 +344,7 @@ func checkEmptyRoute(t *testing.T, client client.Client, name, namespace string) func checkRouteBound(t *testing.T, client client.Client, name, namespace, parent string) { t.Helper() - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { var route gwv1beta1.HTTPRoute err := client.Get(context.Background(), types.NamespacedName{Name: name, Namespace: namespace}, &route) require.NoError(r, err) diff --git a/acceptance/tests/api-gateway/api_gateway_tenancy_test.go b/acceptance/tests/api-gateway/api_gateway_tenancy_test.go index 19e85d60b0..f7b0ac6d79 100644 --- a/acceptance/tests/api-gateway/api_gateway_tenancy_test.go +++ b/acceptance/tests/api-gateway/api_gateway_tenancy_test.go @@ -131,7 +131,7 @@ func TestAPIGateway_Tenancy(t *testing.T) { k8sClient := ctx.ControllerRuntimeClient(t) consulClient, _ := consulCluster.SetupConsulClient(t, c.secure) - retryCheck(t, 60, func(r *retry.R) { + retryCheck(t, 120, func(r *retry.R) { var gateway gwv1beta1.Gateway err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: gatewayNamespace}, &gateway) require.NoError(r, err) @@ -153,7 +153,7 @@ func TestAPIGateway_Tenancy(t *testing.T) { checkConsulNotExists(t, consulClient, api.APIGateway, "gateway", namespaceForConsul(c.namespaceMirroring, gatewayNamespace)) // route failure - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { var httproute gwv1beta1.HTTPRoute err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "route", Namespace: routeNamespace}, &httproute) require.NoError(r, err) @@ -175,7 +175,7 @@ func TestAPIGateway_Tenancy(t *testing.T) { createReferenceGrant(t, k8sClient, "route-service", routeNamespace, serviceNamespace) // gateway updated with references allowed - retryCheck(t, 30, func(r *retry.R) { + retryCheck(t, 60, func(r *retry.R) { var gateway gwv1beta1.Gateway err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: gatewayNamespace}, &gateway) require.NoError(r, err) diff --git a/acceptance/tests/api-gateway/api_gateway_test.go b/acceptance/tests/api-gateway/api_gateway_test.go index 4b4db38afe..721bbf2527 100644 --- a/acceptance/tests/api-gateway/api_gateway_test.go +++ b/acceptance/tests/api-gateway/api_gateway_test.go @@ -101,6 +101,11 @@ func TestAPIGateway_Basic(t *testing.T) { logger.Log(t, "creating target http server") k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + // We use the static-client pod so that we can make calls to the api gateway + // via kubectl exec without needing a route into the cluster from the test machine. + logger.Log(t, "creating static-client pod") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") + logger.Log(t, "patching route to target http server") k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "httproute", "http-route", "-p", `{"spec":{"rules":[{"backendRefs":[{"name":"static-server","port":80}]}]}}`, "--type=merge") @@ -115,11 +120,6 @@ func TestAPIGateway_Basic(t *testing.T) { k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-f", "../fixtures/cases/api-gateways/tcproute/route.yaml") }) - // We use the static-client pod so that we can make calls to the api gateway - // via kubectl exec without needing a route into the cluster from the test machine. - logger.Log(t, "creating static-client pod") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") - // Grab a kubernetes client so that we can verify binding // behavior prior to issuing requests through the gateway. k8sClient := ctx.ControllerRuntimeClient(t) @@ -128,7 +128,7 @@ func TestAPIGateway_Basic(t *testing.T) { // leader election so we may need to wait a long time for // the reconcile loop to run (hence the 1m timeout here). var gatewayAddress string - counter := &retry.Counter{Count: 60, Wait: 2 * time.Second} + counter := &retry.Counter{Count: 120, Wait: 2 * time.Second} retry.RunWith(counter, t, func(r *retry.R) { var gateway gwv1beta1.Gateway err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: "default"}, &gateway) @@ -209,17 +209,22 @@ func TestAPIGateway_Basic(t *testing.T) { checkStatusCondition(t, tcpRoute.Status.Parents[0].Conditions, trueCondition("ConsulAccepted", "Accepted")) // check that the Consul entries were created - entry, _, err := consulClient.ConfigEntries().Get(api.APIGateway, "gateway", nil) - require.NoError(t, err) - gateway := entry.(*api.APIGatewayConfigEntry) + var gateway *api.APIGatewayConfigEntry + var httpRoute *api.HTTPRouteConfigEntry + var route *api.TCPRouteConfigEntry + retry.RunWith(counter, t, func(r *retry.R) { + entry, _, err := consulClient.ConfigEntries().Get(api.APIGateway, "gateway", nil) + require.NoError(r, err) + gateway = entry.(*api.APIGatewayConfigEntry) - entry, _, err = consulClient.ConfigEntries().Get(api.HTTPRoute, "http-route", nil) - require.NoError(t, err) - httpRoute := entry.(*api.HTTPRouteConfigEntry) + entry, _, err = consulClient.ConfigEntries().Get(api.HTTPRoute, "http-route", nil) + require.NoError(r, err) + httpRoute = entry.(*api.HTTPRouteConfigEntry) - entry, _, err = consulClient.ConfigEntries().Get(api.TCPRoute, "tcp-route", nil) - require.NoError(t, err) - route := entry.(*api.TCPRouteConfigEntry) + entry, _, err = consulClient.ConfigEntries().Get(api.TCPRoute, "tcp-route", nil) + require.NoError(r, err) + route = entry.(*api.TCPRouteConfigEntry) + }) // now check the gateway status conditions checkConsulStatusCondition(t, gateway.Status.Conditions, trueConsulCondition("Accepted", "Accepted")) diff --git a/acceptance/tests/partitions/partitions_gateway_test.go b/acceptance/tests/partitions/partitions_gateway_test.go index acdb81fa65..a90a790cb6 100644 --- a/acceptance/tests/partitions/partitions_gateway_test.go +++ b/acceptance/tests/partitions/partitions_gateway_test.go @@ -18,6 +18,7 @@ import ( "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" @@ -255,6 +256,16 @@ func TestPartitions_Gateway(t *testing.T) { logger.Log(t, "creating target server in secondary partition cluster") k8s.DeployKustomize(t, secondaryPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + // Check that static-server injected 2 containers. + for _, labelSelector := range []string{"app=static-server"} { + podList, err := secondaryPartitionClusterContext.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), metav1.ListOptions{ + LabelSelector: labelSelector, + }) + require.NoError(t, err) + require.Len(t, podList.Items, 1) + require.Len(t, podList.Items[0].Spec.Containers, 2) + } + logger.Log(t, "patching route to target server") k8s.RunKubectl(t, secondaryPartitionClusterStaticServerOpts, "patch", "httproute", "http-route", "-p", `{"spec":{"rules":[{"backendRefs":[{"group":"consul.hashicorp.com","kind":"MeshService","name":"mesh-service","port":80}]}]}}`, "--type=merge") @@ -293,6 +304,16 @@ func TestPartitions_Gateway(t *testing.T) { logger.Log(t, "creating target server in default partition cluster") k8s.DeployKustomize(t, defaultPartitionClusterStaticServerOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + // Check that static-server injected 2 containers. + for _, labelSelector := range []string{"app=static-server"} { + podList, err := defaultPartitionClusterContext.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), metav1.ListOptions{ + LabelSelector: labelSelector, + }) + require.NoError(t, err) + require.Len(t, podList.Items, 1) + require.Len(t, podList.Items[0].Spec.Containers, 2) + } + logger.Log(t, "creating exported services") k8s.KubectlApplyK(t, defaultPartitionClusterContext.KubectlOptions(t), "../fixtures/cases/crd-partitions/default-partition-ns1") helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { From 671675d49fbca59272fbbd54becd6366620704a5 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Mon, 7 Aug 2023 22:47:05 -0400 Subject: [PATCH 105/120] NET-3908: allow configuration of SecurityContextConstraints when running on OpenShift (#2184) Co-authored-by: Melisa Griffin --- .changelog/2184.txt | 3 + .../templates/connect-inject-clusterrole.yaml | 10 +++ .../templates/crd-gatewayclassconfigs.yaml | 4 ++ .../templates/gateway-resources-job.yaml | 3 + .../test/unit/connect-inject-clusterrole.bats | 24 +++++++ .../test/unit/gateway-resources-job.bats | 17 +++++ charts/consul/values.yaml | 5 ++ cli/helm/values.go | 11 +-- .../api-gateway/common/helm_config.go | 6 +- .../api-gateway/gatekeeper/gatekeeper.go | 2 +- .../api-gateway/gatekeeper/gatekeeper_test.go | 72 ++++++++++++++++--- control-plane/api-gateway/gatekeeper/init.go | 19 ++--- control-plane/api-gateway/gatekeeper/role.go | 15 +++- .../api-gateway/gatekeeper/rolebinding.go | 4 +- .../api-gateway/gatekeeper/serviceaccount.go | 2 +- .../api/v1alpha1/api_gateway_types.go | 3 + .../api/v1alpha1/api_gateway_types_test.go | 1 + .../subcommand/gateway-resources/command.go | 6 ++ .../gateway-resources/command_test.go | 2 + 19 files changed, 180 insertions(+), 29 deletions(-) create mode 100644 .changelog/2184.txt diff --git a/.changelog/2184.txt b/.changelog/2184.txt new file mode 100644 index 0000000000..bdcb6039fd --- /dev/null +++ b/.changelog/2184.txt @@ -0,0 +1,3 @@ +```release-note:feature +api-gateway: support deploying to OpenShift 4.11 +``` diff --git a/charts/consul/templates/connect-inject-clusterrole.yaml b/charts/consul/templates/connect-inject-clusterrole.yaml index 8c0bbe9bf7..f1f6b3878f 100644 --- a/charts/consul/templates/connect-inject-clusterrole.yaml +++ b/charts/consul/templates/connect-inject-clusterrole.yaml @@ -186,4 +186,14 @@ rules: - "get" - "list" - "watch" +{{- if .Values.global.openshift.enabled }} +- apiGroups: + - security.openshift.io + resources: + - securitycontextconstraints + resourceNames: + - {{ .Values.connectInject.apiGateway.managedGatewayClass.openshiftSCCName }} + verbs: + - use + {{- end }} {{- end }} diff --git a/charts/consul/templates/crd-gatewayclassconfigs.yaml b/charts/consul/templates/crd-gatewayclassconfigs.yaml index 4ab6570e31..38625c9368 100644 --- a/charts/consul/templates/crd-gatewayclassconfigs.yaml +++ b/charts/consul/templates/crd-gatewayclassconfigs.yaml @@ -138,6 +138,10 @@ spec: type: string type: object type: array + openshiftSCCName: + description: The name of an existing SecurityContextConstraints + resource to bind to the managed role when running on OpenShift. + type: string type: object type: object served: true diff --git a/charts/consul/templates/gateway-resources-job.yaml b/charts/consul/templates/gateway-resources-job.yaml index 1fa712759d..048af9fc26 100644 --- a/charts/consul/templates/gateway-resources-job.yaml +++ b/charts/consul/templates/gateway-resources-job.yaml @@ -99,6 +99,9 @@ spec: - {{- toYaml .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service.annotations | nindent 14 -}} {{- end }} - -service-type={{ .Values.connectInject.apiGateway.managedGatewayClass.serviceType }} + {{- if .Values.global.openshift.enabled }} + - -openshift-scc-name={{ .Values.connectInject.apiGateway.managedGatewayClass.openshiftSCCName }} + {{- end }} {{- end}} resources: requests: diff --git a/charts/consul/test/unit/connect-inject-clusterrole.bats b/charts/consul/test/unit/connect-inject-clusterrole.bats index ace8c18d4a..d02b9eacde 100644 --- a/charts/consul/test/unit/connect-inject-clusterrole.bats +++ b/charts/consul/test/unit/connect-inject-clusterrole.bats @@ -217,3 +217,27 @@ load _helpers local actual=$(echo $object | yq -r '.verbs | index("watch")' | tee /dev/stderr) [ "${actual}" != null ] } + +#-------------------------------------------------------------------- +# openshift + +@test "connectInject/ClusterRole: adds permission to securitycontextconstraints for Openshift with global.openshift.enabled=true with default apiGateway Openshift SCC Name" { + cd `chart_dir` + local object=$(helm template \ + -s templates/connect-inject-clusterrole.yaml \ + --set 'global.openshift.enabled=true' \ + . | tee /dev/stderr | + yq '.rules[13].resourceNames | index("restricted-v2")' | tee /dev/stderr) + [ "${object}" == 0 ] +} + +@test "connectInject/ClusterRole: adds permission to securitycontextconstraints for Openshift with global.openshift.enabled=true and sets apiGateway Openshift SCC Name" { + cd `chart_dir` + local object=$(helm template \ + -s templates/connect-inject-clusterrole.yaml \ + --set 'global.openshift.enabled=true' \ + --set 'connectInject.apiGateway.managedGatewayClass.openshiftSCCName=fakescc' \ + . | tee /dev/stderr | + yq '.rules[13].resourceNames | index("fakescc")' | tee /dev/stderr) + [ "${object}" == 0 ] +} diff --git a/charts/consul/test/unit/gateway-resources-job.bats b/charts/consul/test/unit/gateway-resources-job.bats index d79838770d..09322bd2a7 100644 --- a/charts/consul/test/unit/gateway-resources-job.bats +++ b/charts/consul/test/unit/gateway-resources-job.bats @@ -92,6 +92,7 @@ target=templates/gateway-resources-job.yaml --set 'connectInject.apiGateway.managedGatewayClass.tolerations=- key: bar' \ --set 'connectInject.apiGateway.managedGatewayClass.copyAnnotations.service.annotations=- bingo' \ --set 'connectInject.apiGateway.managedGatewayClass.serviceType=Foo' \ + --set 'connectInject.apiGateway.managedGatewayClass.openshiftSCCName=hello' \ . | tee /dev/stderr | yq '.spec.template.spec.containers[0].args' | tee /dev/stderr) @@ -121,6 +122,22 @@ target=templates/gateway-resources-job.yaml local actual=$(echo "$spec" | jq '.[16]') [ "${actual}" = "\"- bingo\"" ] + + local actual=$(echo "$spec" | jq '.[17]') + [ "${actual}" = "\"-service-type=Foo\"" ] +} + +@test "apiGateway/GatewayClassConfig: custom configuration openshift enabled" { + cd `chart_dir` + local spec=$(helm template \ + -s $target \ + --set 'global.openshift.enabled=true' \ + --set 'connectInject.apiGateway.managedGatewayClass.openshiftSCCName=hello' \ + . | tee /dev/stderr | + yq '.spec.template.spec.containers[0].args' | tee /dev/stderr) + + local actual=$(echo "$spec" | jq '.[13]') + [ "${actual}" = "\"-openshift-scc-name=hello\"" ] } diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index d373a240f0..487b6f9ac1 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -2201,6 +2201,11 @@ connectInject: maxInstances: 1 minInstances: 1 + # The name of the OpenShift SecurityContextConstraints resource to use for Gateways. + # Only applicable if `global.openshift.enabled` is true. + # @type: string + openshiftSCCName: "restricted-v2" + # Configuration for the ServiceAccount created for the api-gateway component serviceAccount: # This value defines additional annotations for the client service account. This should be formatted as a multi-line diff --git a/cli/helm/values.go b/cli/helm/values.go index 06671382d1..31b3508e80 100644 --- a/cli/helm/values.go +++ b/cli/helm/values.go @@ -576,11 +576,12 @@ type CopyAnnotations struct { } type ManagedGatewayClass struct { - Enabled bool `yaml:"enabled"` - NodeSelector interface{} `yaml:"nodeSelector"` - ServiceType string `yaml:"serviceType"` - UseHostPorts bool `yaml:"useHostPorts"` - CopyAnnotations CopyAnnotations `yaml:"copyAnnotations"` + Enabled bool `yaml:"enabled"` + NodeSelector interface{} `yaml:"nodeSelector"` + ServiceType string `yaml:"serviceType"` + UseHostPorts bool `yaml:"useHostPorts"` + CopyAnnotations CopyAnnotations `yaml:"copyAnnotations"` + OpenshiftSCCName string `yaml:"openshiftSCCName"` } type Service struct { diff --git a/control-plane/api-gateway/common/helm_config.go b/control-plane/api-gateway/common/helm_config.go index f0d4dc7988..d83b298d92 100644 --- a/control-plane/api-gateway/common/helm_config.go +++ b/control-plane/api-gateway/common/helm_config.go @@ -11,6 +11,7 @@ import ( const componentAuthMethod = "k8s-component-auth-method" // HelmConfig is the configuration of gateways that comes in from the user's Helm values. +// This is a combination of the apiGateway stanza and other settings that impact api-gateways. type HelmConfig struct { // ImageDataplane is the Consul Dataplane image to use in gateway deployments. ImageDataplane string @@ -18,7 +19,6 @@ type HelmConfig struct { ConsulDestinationNamespace string NamespaceMirroringPrefix string EnableNamespaces bool - EnableOpenShift bool EnableNamespaceMirroring bool AuthMethod string // LogLevel is the logging level of the deployed Consul Dataplanes. @@ -30,6 +30,10 @@ type HelmConfig struct { ConsulTLSServerName string ConsulCACert string ConsulConfig ConsulConfig + + // EnableOpenShift indicates whether we're deploying into an OpenShift environment + // and should create SecurityContextConstraints. + EnableOpenShift bool } type ConsulConfig struct { diff --git a/control-plane/api-gateway/gatekeeper/gatekeeper.go b/control-plane/api-gateway/gatekeeper/gatekeeper.go index 19444831ee..6cb7170fc8 100644 --- a/control-plane/api-gateway/gatekeeper/gatekeeper.go +++ b/control-plane/api-gateway/gatekeeper/gatekeeper.go @@ -96,7 +96,7 @@ func (g *Gatekeeper) namespacedName(gateway gwv1beta1.Gateway) types.NamespacedN } func (g *Gatekeeper) serviceAccountName(gateway gwv1beta1.Gateway, config common.HelmConfig) string { - if config.AuthMethod == "" { + if config.AuthMethod == "" && !config.EnableOpenShift { return "" } return gateway.Name diff --git a/control-plane/api-gateway/gatekeeper/gatekeeper_test.go b/control-plane/api-gateway/gatekeeper/gatekeeper_test.go index 069643e301..30cc78d464 100644 --- a/control-plane/api-gateway/gatekeeper/gatekeeper_test.go +++ b/control-plane/api-gateway/gatekeeper/gatekeeper_test.go @@ -193,7 +193,7 @@ func TestUpsert(t *testing.T) { configureDeployment(name, namespace, labels, 3, nil, nil, "", "1"), }, roles: []*rbac.Role{ - configureRole(name, namespace, labels, "1"), + configureRole(name, namespace, labels, "1", false), }, roleBindings: []*rbac.RoleBinding{ configureRoleBinding(name, namespace, labels, "1"), @@ -319,7 +319,7 @@ func TestUpsert(t *testing.T) { configureDeployment(name, namespace, labels, 3, nil, nil, "", "1"), }, roles: []*rbac.Role{ - configureRole(name, namespace, labels, "1"), + configureRole(name, namespace, labels, "1", false), }, roleBindings: []*rbac.RoleBinding{ configureRoleBinding(name, namespace, labels, "1"), @@ -342,7 +342,7 @@ func TestUpsert(t *testing.T) { configureDeployment(name, namespace, labels, 3, nil, nil, "", "2"), }, roles: []*rbac.Role{ - configureRole(name, namespace, labels, "1"), + configureRole(name, namespace, labels, "1", false), }, roleBindings: []*rbac.RoleBinding{ configureRoleBinding(name, namespace, labels, "1"), @@ -400,7 +400,7 @@ func TestUpsert(t *testing.T) { configureDeployment(name, namespace, labels, 3, nil, nil, "", "1"), }, roles: []*rbac.Role{ - configureRole(name, namespace, labels, "1"), + configureRole(name, namespace, labels, "1", false), }, roleBindings: []*rbac.RoleBinding{ configureRoleBinding(name, namespace, labels, "1"), @@ -428,7 +428,7 @@ func TestUpsert(t *testing.T) { configureDeployment(name, namespace, labels, 3, nil, nil, "", "2"), }, roles: []*rbac.Role{ - configureRole(name, namespace, labels, "1"), + configureRole(name, namespace, labels, "1", false), }, roleBindings: []*rbac.RoleBinding{ configureRoleBinding(name, namespace, labels, "1"), @@ -603,6 +603,50 @@ func TestUpsert(t *testing.T) { serviceAccounts: []*corev1.ServiceAccount{}, }, }, + "create a new gateway with openshift enabled": { + gateway: gwv1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: gwv1beta1.GatewaySpec{ + Listeners: listeners, + }, + }, + gatewayClassConfig: v1alpha1.GatewayClassConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "consul-gatewayclassconfig", + }, + Spec: v1alpha1.GatewayClassConfigSpec{ + DeploymentSpec: v1alpha1.DeploymentSpec{ + DefaultInstances: common.PointerTo(int32(3)), + MaxInstances: common.PointerTo(int32(3)), + MinInstances: common.PointerTo(int32(1)), + }, + CopyAnnotations: v1alpha1.CopyAnnotationsSpec{}, + OpenshiftSCCName: "test-api-gateway", + }, + }, + helmConfig: common.HelmConfig{ + EnableOpenShift: true, + }, + initialResources: resources{}, + finalResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 3, nil, nil, "", "1"), + }, + roles: []*rbac.Role{ + configureRole(name, namespace, labels, "1", true), + }, + roleBindings: []*rbac.RoleBinding{ + configureRoleBinding(name, namespace, labels, "1"), + }, + services: []*corev1.Service{}, + serviceAccounts: []*corev1.ServiceAccount{ + configureServiceAccount(name, namespace, labels, "1"), + }, + }, + }, } for name, tc := range cases { @@ -754,7 +798,7 @@ func TestDelete(t *testing.T) { configureDeployment(name, namespace, labels, 3, nil, nil, "", "1"), }, roles: []*rbac.Role{ - configureRole(name, namespace, labels, "1"), + configureRole(name, namespace, labels, "1", false), }, roleBindings: []*rbac.RoleBinding{ configureRoleBinding(name, namespace, labels, "1"), @@ -1057,7 +1101,19 @@ func configureDeployment(name, namespace string, labels map[string]string, repli } } -func configureRole(name, namespace string, labels map[string]string, resourceVersion string) *rbac.Role { +func configureRole(name, namespace string, labels map[string]string, resourceVersion string, openshiftEnabled bool) *rbac.Role { + rules := []rbac.PolicyRule{} + + if openshiftEnabled { + rules = []rbac.PolicyRule{ + { + APIGroups: []string{"security.openshift.io"}, + Resources: []string{"securitycontextconstraints"}, + ResourceNames: []string{name + "-api-gateway"}, + Verbs: []string{"use"}, + }, + } + } return &rbac.Role{ TypeMeta: metav1.TypeMeta{ APIVersion: "rbac.authorization.k8s.io/v1", @@ -1078,7 +1134,7 @@ func configureRole(name, namespace string, labels map[string]string, resourceVer }, }, }, - Rules: []rbac.PolicyRule{}, + Rules: rules, } } diff --git a/control-plane/api-gateway/gatekeeper/init.go b/control-plane/api-gateway/gatekeeper/init.go index 35360b7f87..f3d4ad1f95 100644 --- a/control-plane/api-gateway/gatekeeper/init.go +++ b/control-plane/api-gateway/gatekeeper/init.go @@ -168,14 +168,17 @@ func initContainer(config common.HelmConfig, name, namespace string) (corev1.Con }) } - container.SecurityContext = &corev1.SecurityContext{ - RunAsUser: pointer.Int64(initContainersUserAndGroupID), - RunAsGroup: pointer.Int64(initContainersUserAndGroupID), - RunAsNonRoot: pointer.Bool(true), - Privileged: pointer.Bool(false), - Capabilities: &corev1.Capabilities{ - Drop: []corev1.Capability{"ALL"}, - }, + // Openshift Assigns the security context for us, do not enable if it is enabled. + if !config.EnableOpenShift { + container.SecurityContext = &corev1.SecurityContext{ + RunAsUser: pointer.Int64(initContainersUserAndGroupID), + RunAsGroup: pointer.Int64(initContainersUserAndGroupID), + RunAsNonRoot: pointer.Bool(true), + Privileged: pointer.Bool(false), + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + } } return container, nil diff --git a/control-plane/api-gateway/gatekeeper/role.go b/control-plane/api-gateway/gatekeeper/role.go index eb8431075a..705e9bffff 100644 --- a/control-plane/api-gateway/gatekeeper/role.go +++ b/control-plane/api-gateway/gatekeeper/role.go @@ -19,7 +19,7 @@ import ( ) func (g *Gatekeeper) upsertRole(ctx context.Context, gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClassConfig, config common.HelmConfig) error { - if config.AuthMethod == "" { + if config.AuthMethod == "" && !config.EnableOpenShift { return g.deleteRole(ctx, types.NamespacedName{Namespace: gateway.Namespace, Name: gateway.Name}) } @@ -40,7 +40,7 @@ func (g *Gatekeeper) upsertRole(ctx context.Context, gateway gwv1beta1.Gateway, return errors.New("role not owned by controller") } - role = g.role(gateway, gcc) + role = g.role(gateway, gcc, config) if err := ctrl.SetControllerReference(&gateway, role, g.Client.Scheme()); err != nil { return err } @@ -62,7 +62,7 @@ func (g *Gatekeeper) deleteRole(ctx context.Context, gwName types.NamespacedName return nil } -func (g *Gatekeeper) role(gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClassConfig) *rbac.Role { +func (g *Gatekeeper) role(gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClassConfig, config common.HelmConfig) *rbac.Role { role := &rbac.Role{ ObjectMeta: metav1.ObjectMeta{ Name: gateway.Name, @@ -81,5 +81,14 @@ func (g *Gatekeeper) role(gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClassCo }) } + if config.EnableOpenShift { + role.Rules = append(role.Rules, rbac.PolicyRule{ + APIGroups: []string{"security.openshift.io"}, + Resources: []string{"securitycontextconstraints"}, + ResourceNames: []string{gcc.Spec.OpenshiftSCCName}, + Verbs: []string{"use"}, + }) + } + return role } diff --git a/control-plane/api-gateway/gatekeeper/rolebinding.go b/control-plane/api-gateway/gatekeeper/rolebinding.go index 8891a754e6..1a60e752c8 100644 --- a/control-plane/api-gateway/gatekeeper/rolebinding.go +++ b/control-plane/api-gateway/gatekeeper/rolebinding.go @@ -19,7 +19,7 @@ import ( ) func (g *Gatekeeper) upsertRoleBinding(ctx context.Context, gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClassConfig, config common.HelmConfig) error { - if config.AuthMethod == "" { + if config.AuthMethod == "" && !config.EnableOpenShift { return g.deleteRole(ctx, types.NamespacedName{Namespace: gateway.Namespace, Name: gateway.Name}) } @@ -66,7 +66,7 @@ func (g *Gatekeeper) deleteRoleBinding(ctx context.Context, gwName types.Namespa func (g *Gatekeeper) roleBinding(gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClassConfig, config common.HelmConfig) *rbac.RoleBinding { // Create resources for reference. This avoids bugs if naming patterns change. serviceAccount := g.serviceAccount(gateway) - role := g.role(gateway, gcc) + role := g.role(gateway, gcc, config) return &rbac.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ diff --git a/control-plane/api-gateway/gatekeeper/serviceaccount.go b/control-plane/api-gateway/gatekeeper/serviceaccount.go index 47336867aa..d1c5c9883a 100644 --- a/control-plane/api-gateway/gatekeeper/serviceaccount.go +++ b/control-plane/api-gateway/gatekeeper/serviceaccount.go @@ -18,7 +18,7 @@ import ( ) func (g *Gatekeeper) upsertServiceAccount(ctx context.Context, gateway gwv1beta1.Gateway, config common.HelmConfig) error { - if config.AuthMethod == "" { + if config.AuthMethod == "" && !config.EnableOpenShift { return g.deleteServiceAccount(ctx, types.NamespacedName{Namespace: gateway.Namespace, Name: gateway.Name}) } diff --git a/control-plane/api/v1alpha1/api_gateway_types.go b/control-plane/api/v1alpha1/api_gateway_types.go index f9be4bdb47..7f0b958701 100644 --- a/control-plane/api/v1alpha1/api_gateway_types.go +++ b/control-plane/api/v1alpha1/api_gateway_types.go @@ -59,6 +59,9 @@ type GatewayClassConfigSpec struct { // The name of an existing Kubernetes PodSecurityPolicy to bind to the managed ServiceAccount if ACLs are managed. PodSecurityPolicy string `json:"podSecurityPolicy,omitempty"` + + // The name of the OpenShift SecurityContextConstraints resource for this gateway class to use. + OpenshiftSCCName string `json:"openshiftSCCName,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/control-plane/api/v1alpha1/api_gateway_types_test.go b/control-plane/api/v1alpha1/api_gateway_types_test.go index 1f9d8ebef0..6e0690b9b2 100644 --- a/control-plane/api/v1alpha1/api_gateway_types_test.go +++ b/control-plane/api/v1alpha1/api_gateway_types_test.go @@ -21,6 +21,7 @@ func TestGatewayClassConfigDeepCopy(t *testing.T) { NodeSelector: map[string]string{ "test": "test", }, + OpenshiftSCCName: "restricted-v2", } config := &GatewayClassConfig{ ObjectMeta: metav1.ObjectMeta{ diff --git a/control-plane/subcommand/gateway-resources/command.go b/control-plane/subcommand/gateway-resources/command.go index 2da2abccb1..3ad3ff7f53 100644 --- a/control-plane/subcommand/gateway-resources/command.go +++ b/control-plane/subcommand/gateway-resources/command.go @@ -71,6 +71,8 @@ type Command struct { flagTolerations string // this is a multiline yaml string matching the tolerations array flagServiceAnnotations string // this is a multiline yaml string array of annotations to allow + flagOpenshiftSCCName string + k8sClient client.Client once sync.Once @@ -123,6 +125,9 @@ func (c *Command) init() { c.flags.StringVar(&c.flagServiceAnnotations, "service-annotations", "", "The annotations to copy over from a gateway to its service.", ) + c.flags.StringVar(&c.flagOpenshiftSCCName, "openshift-scc-name", "", + "Name of security context constraint to use for gateways on Openshift.", + ) c.k8s = &flags.K8SFlags{} flags.Merge(c.flags, c.k8s.Flags()) @@ -197,6 +202,7 @@ func (c *Command) Run(args []string) int { MaxInstances: nonZeroOrNil(c.flagDeploymentMaxInstances), MinInstances: nonZeroOrNil(c.flagDeploymentMinInstances), }, + OpenshiftSCCName: c.flagOpenshiftSCCName, }, } diff --git a/control-plane/subcommand/gateway-resources/command_test.go b/control-plane/subcommand/gateway-resources/command_test.go index 0c40e67244..f60e376042 100644 --- a/control-plane/subcommand/gateway-resources/command_test.go +++ b/control-plane/subcommand/gateway-resources/command_test.go @@ -163,6 +163,7 @@ bar: 2`, flagServiceAnnotations: ` - foo - bar`, + flagOpenshiftSCCName: "restricted-v2", }, }, } { @@ -245,6 +246,7 @@ func TestRun(t *testing.T) { "-release-name", "test", "-component", "test", "-controller-name", "test", + "-openshift-scc-name", "restricted-v2", }) require.Equal(t, 0, code) From 71cdbc24fa8ad3bf3571b4c71744a5171cafdd50 Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Tue, 8 Aug 2023 10:47:26 -0400 Subject: [PATCH 106/120] Gateway privileged port mapping (#2707) * Adds port mapping to Gateway Class Config to avoid running container on privileged ports Co-authored-by: Nathan Coleman --- .changelog/2707.txt | 3 + .../templates/crd-gatewayclassconfigs.yaml | 9 ++ .../templates/gateway-resources-job.yaml | 1 + charts/consul/values.yaml | 6 + cli/helm/values.go | 13 +- control-plane/api-gateway/binding/binder.go | 4 +- control-plane/api-gateway/binding/result.go | 8 +- .../api-gateway/binding/validation.go | 19 ++- .../api-gateway/binding/validation_test.go | 31 ++++- .../api-gateway/common/helm_config.go | 4 + .../api-gateway/common/translation.go | 22 +++- .../api-gateway/common/translation_test.go | 2 +- .../api-gateway/gatekeeper/gatekeeper_test.go | 112 ++++++++++++++---- .../api-gateway/gatekeeper/service.go | 6 +- .../api/v1alpha1/api_gateway_types.go | 3 + .../subcommand/gateway-resources/command.go | 9 +- 16 files changed, 209 insertions(+), 43 deletions(-) create mode 100644 .changelog/2707.txt diff --git a/.changelog/2707.txt b/.changelog/2707.txt new file mode 100644 index 0000000000..370aaa7c17 --- /dev/null +++ b/.changelog/2707.txt @@ -0,0 +1,3 @@ +```release-note:feature +api-gateway: adds ability to map privileged ports on Gateway listeners to unprivileged ports so that containers do not require additional privileges +``` diff --git a/charts/consul/templates/crd-gatewayclassconfigs.yaml b/charts/consul/templates/crd-gatewayclassconfigs.yaml index 38625c9368..8140902f78 100644 --- a/charts/consul/templates/crd-gatewayclassconfigs.yaml +++ b/charts/consul/templates/crd-gatewayclassconfigs.yaml @@ -142,6 +142,15 @@ spec: description: The name of an existing SecurityContextConstraints resource to bind to the managed role when running on OpenShift. type: string + mapPrivilegedContainerPorts: + type: integer + format: int32 + minimum: 0 + maximum: 64512 + description: mapPrivilegedContainerPorts is the value which Consul will add to privileged container port + values (ports < 1024) defined on a Gateway when the number is greater than 0. This cannot be more than + 64512 as the highest privileged port is 1023, which would then map to 65535, which is the highest + valid port number. type: object type: object served: true diff --git a/charts/consul/templates/gateway-resources-job.yaml b/charts/consul/templates/gateway-resources-job.yaml index 048af9fc26..de64e2d70d 100644 --- a/charts/consul/templates/gateway-resources-job.yaml +++ b/charts/consul/templates/gateway-resources-job.yaml @@ -102,6 +102,7 @@ spec: {{- if .Values.global.openshift.enabled }} - -openshift-scc-name={{ .Values.connectInject.apiGateway.managedGatewayClass.openshiftSCCName }} {{- end }} + - -map-privileged-container-ports={{ .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} {{- end}} resources: requests: diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 487b6f9ac1..954680262a 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -2206,6 +2206,12 @@ connectInject: # @type: string openshiftSCCName: "restricted-v2" + # This value defines the amount we will add to privileged container ports on gateways that use this class. + # This is useful if you don't want to give your containers extra permissions to run privileged ports. + # Example: The gateway listener is defined on port 80, but the underlying value of the port on the container + # will be the 80 + the number defined below. + mapPrivilegedContainerPorts: 0 + # Configuration for the ServiceAccount created for the api-gateway component serviceAccount: # This value defines additional annotations for the client service account. This should be formatted as a multi-line diff --git a/cli/helm/values.go b/cli/helm/values.go index 31b3508e80..19e19d8d05 100644 --- a/cli/helm/values.go +++ b/cli/helm/values.go @@ -576,12 +576,13 @@ type CopyAnnotations struct { } type ManagedGatewayClass struct { - Enabled bool `yaml:"enabled"` - NodeSelector interface{} `yaml:"nodeSelector"` - ServiceType string `yaml:"serviceType"` - UseHostPorts bool `yaml:"useHostPorts"` - CopyAnnotations CopyAnnotations `yaml:"copyAnnotations"` - OpenshiftSCCName string `yaml:"openshiftSCCName"` + Enabled bool `yaml:"enabled"` + NodeSelector interface{} `yaml:"nodeSelector"` + ServiceType string `yaml:"serviceType"` + UseHostPorts bool `yaml:"useHostPorts"` + CopyAnnotations CopyAnnotations `yaml:"copyAnnotations"` + OpenshiftSCCName string `yaml:"openshiftSCCName"` + MapPrivilegedContainerPorts int `yaml:"mapPrivilegedContainerPorts"` } type Service struct { diff --git a/control-plane/api-gateway/binding/binder.go b/control-plane/api-gateway/binding/binder.go index 7fbf18d412..7798a6b49c 100644 --- a/control-plane/api-gateway/binding/binder.go +++ b/control-plane/api-gateway/binding/binder.go @@ -132,7 +132,7 @@ func (b *Binder) Snapshot() *Snapshot { // calculate the status for the gateway gatewayValidation = validateGateway(b.config.Gateway, registrationPods, b.config.ConsulGateway) - listenerValidation = validateListeners(b.config.Gateway, b.config.Gateway.Spec.Listeners, b.config.Resources) + listenerValidation = validateListeners(b.config.Gateway, b.config.Gateway.Spec.Listeners, b.config.Resources, b.config.GatewayClassConfig) } // used for tracking how many routes have successfully bound to which listeners @@ -182,7 +182,7 @@ func (b *Binder) Snapshot() *Snapshot { if b.config.ConsulGateway != nil { consulStatus = b.config.ConsulGateway.Status } - entry := b.config.Translator.ToAPIGateway(b.config.Gateway, b.config.Resources) + entry := b.config.Translator.ToAPIGateway(b.config.Gateway, b.config.Resources, gatewayClassConfig) snapshot.Consul.Updates = append(snapshot.Consul.Updates, &common.ConsulUpdateOperation{ Entry: entry, OnUpdate: b.handleGatewaySyncStatus(snapshot, &b.config.Gateway, consulStatus), diff --git a/control-plane/api-gateway/binding/result.go b/control-plane/api-gateway/binding/result.go index b148e441e2..1953d4836c 100644 --- a/control-plane/api-gateway/binding/result.go +++ b/control-plane/api-gateway/binding/result.go @@ -242,6 +242,12 @@ var ( // We map anything under here to a custom ListenerConditionReason of Invalid on // an Accepted status type. errListenerNoTLSPassthrough = errors.New("TLS passthrough is not supported") + + // This custom listener validation error is used to differentiate between an errListenerPortUnavailable because of + // direct port conflicts defined by the user (two listeners on the same port) vs a port conflict because we map + // privileged ports by adding the value passed into the gatewayClassConfig. + // (i.e. one listener on 80 with a privileged port mapping of 2000, and one listener on 2080 would conflict). + errListenerMappedToPrivilegedPortMapping = errors.New("listener conflicts with privileged port mapped by GatewayClassConfig privileged port mapping setting") ) // listenerValidationResult contains the result of internally validating a single listener @@ -291,7 +297,7 @@ func (l listenerValidationResult) programmedCondition(generation int64) metav1.C func (l listenerValidationResult) acceptedCondition(generation int64) metav1.Condition { now := timeFunc() switch l.acceptedErr { - case errListenerPortUnavailable: + case errListenerPortUnavailable, errListenerMappedToPrivilegedPortMapping: return metav1.Condition{ Type: "Accepted", Status: metav1.ConditionFalse, diff --git a/control-plane/api-gateway/binding/validation.go b/control-plane/api-gateway/binding/validation.go index a57cf598a4..d5a97499ca 100644 --- a/control-plane/api-gateway/binding/validation.go +++ b/control-plane/api-gateway/binding/validation.go @@ -226,7 +226,7 @@ func validateCertificateData(secret corev1.Secret) error { // validateListeners validates the given listeners both internally and with respect to each // other for purposes of setting "Conflicted" status conditions. -func validateListeners(gateway gwv1beta1.Gateway, listeners []gwv1beta1.Listener, resources *common.ResourceMap) listenerValidationResults { +func validateListeners(gateway gwv1beta1.Gateway, listeners []gwv1beta1.Listener, resources *common.ResourceMap, gwcc *v1alpha1.GatewayClassConfig) listenerValidationResults { var results listenerValidationResults merged := make(map[gwv1beta1.PortNumber]mergedListeners) for i, listener := range listeners { @@ -235,7 +235,15 @@ func validateListeners(gateway gwv1beta1.Gateway, listeners []gwv1beta1.Listener listener: listener, }) } - + // This list keeps track of port conflicts directly on gateways. i.e., two listeners on the same port as + // defined by the user. + seenListenerPorts := map[int]struct{}{} + // This list keeps track of port conflicts caused by privileged port mappings. + seenContainerPorts := map[int]struct{}{} + portMapping := int32(0) + if gwcc != nil { + portMapping = gwcc.Spec.MapPrivilegedContainerPorts + } for i, listener := range listeners { var result listenerValidationResult @@ -249,6 +257,10 @@ func validateListeners(gateway gwv1beta1.Gateway, listeners []gwv1beta1.Listener result.acceptedErr = errListenerUnsupportedProtocol } else if listener.Port == 20000 { // admin port result.acceptedErr = errListenerPortUnavailable + } else if _, ok := seenListenerPorts[int(listener.Port)]; ok { + result.acceptedErr = errListenerPortUnavailable + } else if _, ok := seenContainerPorts[common.ToContainerPort(listener.Port, portMapping)]; ok { + result.acceptedErr = errListenerMappedToPrivilegedPortMapping } result.routeKindErr = validateListenerAllowedRouteKinds(listener.AllowedRoutes) @@ -261,6 +273,9 @@ func validateListeners(gateway gwv1beta1.Gateway, listeners []gwv1beta1.Listener } results = append(results, result) + + seenListenerPorts[int(listener.Port)] = struct{}{} + seenContainerPorts[common.ToContainerPort(listener.Port, portMapping)] = struct{}{} } return results } diff --git a/control-plane/api-gateway/binding/validation_test.go b/control-plane/api-gateway/binding/validation_test.go index da0ed83f95..10cdf851c3 100644 --- a/control-plane/api-gateway/binding/validation_test.go +++ b/control-plane/api-gateway/binding/validation_test.go @@ -530,8 +530,10 @@ func TestValidateListeners(t *testing.T) { t.Parallel() for name, tt := range map[string]struct { - listeners []gwv1beta1.Listener - expectedAcceptedErr error + listeners []gwv1beta1.Listener + expectedAcceptedErr error + listenerIndexToTest int + mapPrivilegedContainerPorts int32 }{ "valid protocol HTTP": { listeners: []gwv1beta1.Listener{ @@ -563,9 +565,32 @@ func TestValidateListeners(t *testing.T) { }, expectedAcceptedErr: errListenerPortUnavailable, }, + "conflicted port": { + listeners: []gwv1beta1.Listener{ + {Protocol: gwv1beta1.TCPProtocolType, Port: 80}, + {Protocol: gwv1beta1.TCPProtocolType, Port: 80}, + }, + expectedAcceptedErr: errListenerPortUnavailable, + listenerIndexToTest: 1, + }, + "conflicted mapped port": { + listeners: []gwv1beta1.Listener{ + {Protocol: gwv1beta1.TCPProtocolType, Port: 80}, + {Protocol: gwv1beta1.TCPProtocolType, Port: 2080}, + }, + expectedAcceptedErr: errListenerMappedToPrivilegedPortMapping, + listenerIndexToTest: 1, + mapPrivilegedContainerPorts: 2000, + }, } { t.Run(name, func(t *testing.T) { - require.Equal(t, tt.expectedAcceptedErr, validateListeners(gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), tt.listeners, nil)[0].acceptedErr) + gwcc := &v1alpha1.GatewayClassConfig{ + Spec: v1alpha1.GatewayClassConfigSpec{ + MapPrivilegedContainerPorts: tt.mapPrivilegedContainerPorts, + }, + } + + require.Equal(t, tt.expectedAcceptedErr, validateListeners(gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), tt.listeners, nil, gwcc)[tt.listenerIndexToTest].acceptedErr) }) } } diff --git a/control-plane/api-gateway/common/helm_config.go b/control-plane/api-gateway/common/helm_config.go index d83b298d92..ecd9d42c29 100644 --- a/control-plane/api-gateway/common/helm_config.go +++ b/control-plane/api-gateway/common/helm_config.go @@ -34,6 +34,10 @@ type HelmConfig struct { // EnableOpenShift indicates whether we're deploying into an OpenShift environment // and should create SecurityContextConstraints. EnableOpenShift bool + + // MapPrivilegedServicePorts is the value which Consul will add to privileged container port values (ports < 1024) + // defined on a Gateway. + MapPrivilegedServicePorts int } type ConsulConfig struct { diff --git a/control-plane/api-gateway/common/translation.go b/control-plane/api-gateway/common/translation.go index 94241eed22..2f66749c94 100644 --- a/control-plane/api-gateway/common/translation.go +++ b/control-plane/api-gateway/common/translation.go @@ -55,11 +55,11 @@ func (t ResourceTranslator) Namespace(namespace string) string { } // ToAPIGateway translates a kuberenetes API gateway into a Consul APIGateway Config Entry. -func (t ResourceTranslator) ToAPIGateway(gateway gwv1beta1.Gateway, resources *ResourceMap) *api.APIGatewayConfigEntry { +func (t ResourceTranslator) ToAPIGateway(gateway gwv1beta1.Gateway, resources *ResourceMap, gwcc *v1alpha1.GatewayClassConfig) *api.APIGatewayConfigEntry { namespace := t.Namespace(gateway.Namespace) listeners := ConvertSliceFuncIf(gateway.Spec.Listeners, func(listener gwv1beta1.Listener) (api.APIGatewayListener, bool) { - return t.toAPIGatewayListener(gateway, listener, resources) + return t.toAPIGatewayListener(gateway, listener, resources, gwcc) }) return &api.APIGatewayConfigEntry{ @@ -81,7 +81,7 @@ var listenerProtocolMap = map[string]string{ "tcp": "tcp", } -func (t ResourceTranslator) toAPIGatewayListener(gateway gwv1beta1.Gateway, listener gwv1beta1.Listener, resources *ResourceMap) (api.APIGatewayListener, bool) { +func (t ResourceTranslator) toAPIGatewayListener(gateway gwv1beta1.Gateway, listener gwv1beta1.Listener, resources *ResourceMap, gwcc *v1alpha1.GatewayClassConfig) (api.APIGatewayListener, bool) { namespace := gateway.Namespace var certificates []api.ResourceReference @@ -104,10 +104,15 @@ func (t ResourceTranslator) toAPIGatewayListener(gateway gwv1beta1.Gateway, list } } + portMapping := int32(0) + if gwcc != nil { + portMapping = gwcc.Spec.MapPrivilegedContainerPorts + } + return api.APIGatewayListener{ Name: string(listener.Name), Hostname: DerefStringOr(listener.Hostname, ""), - Port: int(listener.Port), + Port: ToContainerPort(listener.Port, portMapping), Protocol: listenerProtocolMap[strings.ToLower(string(listener.Protocol))], TLS: api.APIGatewayTLSConfiguration{ Certificates: certificates, @@ -115,6 +120,15 @@ func (t ResourceTranslator) toAPIGatewayListener(gateway gwv1beta1.Gateway, list }, true } +func ToContainerPort(portNumber gwv1beta1.PortNumber, mapPrivilegedContainerPorts int32) int { + if portNumber >= 1024 { + // We don't care about privileged port-mapping, this is a non-privileged port + return int(portNumber) + } + + return int(portNumber) + int(mapPrivilegedContainerPorts) +} + func (t ResourceTranslator) ToHTTPRoute(route gwv1beta1.HTTPRoute, resources *ResourceMap) *api.HTTPRouteConfigEntry { namespace := t.Namespace(route.Namespace) diff --git a/control-plane/api-gateway/common/translation_test.go b/control-plane/api-gateway/common/translation_test.go index 20917151f3..daa89a698f 100644 --- a/control-plane/api-gateway/common/translation_test.go +++ b/control-plane/api-gateway/common/translation_test.go @@ -320,7 +320,7 @@ func TestTranslator_ToAPIGateway(t *testing.T) { resources.ReferenceCountCertificate(listenerOneCert) resources.ReferenceCountCertificate(listenerTwoCert) - actualConfigEntry := translator.ToAPIGateway(input, resources) + actualConfigEntry := translator.ToAPIGateway(input, resources, &v1alpha1.GatewayClassConfig{}) if diff := cmp.Diff(expectedConfigEntry, actualConfigEntry); diff != "" { t.Errorf("Translator.GatewayToAPIGateway() mismatch (-want +got):\n%s", diff) diff --git a/control-plane/api-gateway/gatekeeper/gatekeeper_test.go b/control-plane/api-gateway/gatekeeper/gatekeeper_test.go index 30cc78d464..562b139274 100644 --- a/control-plane/api-gateway/gatekeeper/gatekeeper_test.go +++ b/control-plane/api-gateway/gatekeeper/gatekeeper_test.go @@ -19,6 +19,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/intstr" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" @@ -112,6 +113,68 @@ func TestUpsert(t *testing.T) { serviceAccounts: []*corev1.ServiceAccount{}, }, }, + "create a new gateway with service and map privileged ports correctly": { + gateway: gwv1beta1.Gateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: gwv1beta1.GatewaySpec{ + Listeners: []gwv1beta1.Listener{ + { + Name: "Listener 1", + Port: 80, + Protocol: "TCP", + }, + { + Name: "Listener 2", + Port: 8080, + Protocol: "TCP", + }, + }, + }, + }, + gatewayClassConfig: v1alpha1.GatewayClassConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "consul-gatewayclassconfig", + }, + Spec: v1alpha1.GatewayClassConfigSpec{ + DeploymentSpec: v1alpha1.DeploymentSpec{ + DefaultInstances: common.PointerTo(int32(3)), + MaxInstances: common.PointerTo(int32(3)), + MinInstances: common.PointerTo(int32(1)), + }, + CopyAnnotations: v1alpha1.CopyAnnotationsSpec{}, + ServiceType: (*corev1.ServiceType)(common.PointerTo("NodePort")), + MapPrivilegedContainerPorts: 2000, + }, + }, + helmConfig: common.HelmConfig{}, + initialResources: resources{}, + finalResources: resources{ + deployments: []*appsv1.Deployment{ + configureDeployment(name, namespace, labels, 3, nil, nil, "", "1"), + }, + roles: []*rbac.Role{}, + services: []*corev1.Service{ + configureService(name, namespace, labels, nil, (corev1.ServiceType)("NodePort"), []corev1.ServicePort{ + { + Name: "Listener 1", + Protocol: "TCP", + Port: 80, + TargetPort: intstr.FromInt(2080), + }, + { + Name: "Listener 2", + Protocol: "TCP", + Port: 8080, + TargetPort: intstr.FromInt(8080), + }, + }, "1"), + }, + serviceAccounts: []*corev1.ServiceAccount{}, + }, + }, "create a new gateway deployment with managed Service": { gateway: gwv1beta1.Gateway{ ObjectMeta: metav1.ObjectMeta{ @@ -146,14 +209,16 @@ func TestUpsert(t *testing.T) { services: []*corev1.Service{ configureService(name, namespace, labels, nil, (corev1.ServiceType)("NodePort"), []corev1.ServicePort{ { - Name: "Listener 1", - Protocol: "TCP", - Port: 8080, + Name: "Listener 1", + Protocol: "TCP", + Port: 8080, + TargetPort: intstr.FromInt(8080), }, { - Name: "Listener 2", - Protocol: "TCP", - Port: 8081, + Name: "Listener 2", + Protocol: "TCP", + Port: 8081, + TargetPort: intstr.FromInt(8081), }, }, "1"), }, @@ -201,14 +266,16 @@ func TestUpsert(t *testing.T) { services: []*corev1.Service{ configureService(name, namespace, labels, nil, (corev1.ServiceType)("NodePort"), []corev1.ServicePort{ { - Name: "Listener 1", - Protocol: "TCP", - Port: 8080, + Name: "Listener 1", + Protocol: "TCP", + Port: 8080, + TargetPort: intstr.FromInt(8080), }, { - Name: "Listener 2", - Protocol: "TCP", - Port: 8081, + Name: "Listener 2", + Protocol: "TCP", + Port: 8081, + TargetPort: intstr.FromInt(8081), }, }, "1"), }, @@ -350,14 +417,16 @@ func TestUpsert(t *testing.T) { services: []*corev1.Service{ configureService(name, namespace, labels, nil, (corev1.ServiceType)("NodePort"), []corev1.ServicePort{ { - Name: "Listener 1", - Protocol: "TCP", - Port: 8080, + Name: "Listener 1", + Protocol: "TCP", + Port: 8080, + TargetPort: intstr.FromInt(8080), }, { - Name: "Listener 2", - Protocol: "TCP", - Port: 8081, + Name: "Listener 2", + Protocol: "TCP", + Port: 8081, + TargetPort: intstr.FromInt(8081), }, }, "2"), }, @@ -436,9 +505,10 @@ func TestUpsert(t *testing.T) { services: []*corev1.Service{ configureService(name, namespace, labels, nil, (corev1.ServiceType)("NodePort"), []corev1.ServicePort{ { - Name: "Listener 1", - Protocol: "TCP", - Port: 8080, + Name: "Listener 1", + Protocol: "TCP", + Port: 8080, + TargetPort: intstr.FromInt(8080), }, }, "2"), }, diff --git a/control-plane/api-gateway/gatekeeper/service.go b/control-plane/api-gateway/gatekeeper/service.go index d534ad50d7..a30a3df89f 100644 --- a/control-plane/api-gateway/gatekeeper/service.go +++ b/control-plane/api-gateway/gatekeeper/service.go @@ -15,6 +15,7 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/util/intstr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" gwv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" @@ -76,8 +77,9 @@ func (g *Gatekeeper) service(gateway gwv1beta1.Gateway, gcc v1alpha1.GatewayClas ports = append(ports, corev1.ServicePort{ Name: string(listener.Name), // only TCP-based services are supported for now - Protocol: corev1.ProtocolTCP, - Port: int32(listener.Port), + Protocol: corev1.ProtocolTCP, + Port: int32(listener.Port), + TargetPort: intstr.FromInt(common.ToContainerPort(listener.Port, gcc.Spec.MapPrivilegedContainerPorts)), }) seenPorts[listener.Port] = struct{}{} diff --git a/control-plane/api/v1alpha1/api_gateway_types.go b/control-plane/api/v1alpha1/api_gateway_types.go index 7f0b958701..c06ac3825f 100644 --- a/control-plane/api/v1alpha1/api_gateway_types.go +++ b/control-plane/api/v1alpha1/api_gateway_types.go @@ -62,6 +62,9 @@ type GatewayClassConfigSpec struct { // The name of the OpenShift SecurityContextConstraints resource for this gateway class to use. OpenshiftSCCName string `json:"openshiftSCCName,omitempty"` + + // The value to add to privileged ports ( ports < 1024) for gateway containers + MapPrivilegedContainerPorts int32 `json:"mapPrivilegedContainerPorts,omitempty"` } // +k8s:deepcopy-gen=true diff --git a/control-plane/subcommand/gateway-resources/command.go b/control-plane/subcommand/gateway-resources/command.go index 3ad3ff7f53..6deea27a26 100644 --- a/control-plane/subcommand/gateway-resources/command.go +++ b/control-plane/subcommand/gateway-resources/command.go @@ -73,6 +73,8 @@ type Command struct { flagOpenshiftSCCName string + flagMapPrivilegedContainerPorts int + k8sClient client.Client once sync.Once @@ -128,6 +130,10 @@ func (c *Command) init() { c.flags.StringVar(&c.flagOpenshiftSCCName, "openshift-scc-name", "", "Name of security context constraint to use for gateways on Openshift.", ) + c.flags.IntVar(&c.flagMapPrivilegedContainerPorts, "map-privileged-container-ports", 0, + "The value to add to privileged container ports (< 1024) to avoid requiring addition privileges for the "+ + "gateway container.", + ) c.k8s = &flags.K8SFlags{} flags.Merge(c.flags, c.k8s.Flags()) @@ -202,7 +208,8 @@ func (c *Command) Run(args []string) int { MaxInstances: nonZeroOrNil(c.flagDeploymentMaxInstances), MinInstances: nonZeroOrNil(c.flagDeploymentMinInstances), }, - OpenshiftSCCName: c.flagOpenshiftSCCName, + OpenshiftSCCName: c.flagOpenshiftSCCName, + MapPrivilegedContainerPorts: int32(c.flagMapPrivilegedContainerPorts), }, } From a1eb32bae371bb205de5d102ee6c9057bb90fe14 Mon Sep 17 00:00:00 2001 From: Paul Glass Date: Tue, 8 Aug 2023 09:48:18 -0500 Subject: [PATCH 107/120] Support restricted PSA enforcement part 2 (#2702) --- .../framework/connhelper/connect_helper.go | 8 +-- acceptance/framework/k8s/helpers.go | 1 + .../wan-federation/wan_federation_test.go | 50 +++++++++++-------- .../create-federation-secret-job.yaml | 1 + .../ingress-gateways-deployment.yaml | 2 + .../consul/templates/partition-init-job.yaml | 1 + .../templates/sync-catalog-deployment.yaml | 1 + .../terminating-gateways-deployment.yaml | 2 + 8 files changed, 42 insertions(+), 24 deletions(-) diff --git a/acceptance/framework/connhelper/connect_helper.go b/acceptance/framework/connhelper/connect_helper.go index 2eb18c9dbb..314c0d853a 100644 --- a/acceptance/framework/connhelper/connect_helper.go +++ b/acceptance/framework/connhelper/connect_helper.go @@ -123,7 +123,7 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { logger.Log(t, "creating static-server and static-client deployments") - c.setupAppNamespace(t) + c.SetupAppNamespace(t) opts := c.KubectlOptsForApp(t) if c.Cfg.EnableCNI && c.Cfg.EnableOpenshift { @@ -170,10 +170,10 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { }) } -// setupAppNamespace creates a namespace where applications are deployed. This +// SetupAppNamespace creates a namespace where applications are deployed. This // does nothing if UseAppNamespace is not set. The app namespace is relevant // when testing with restricted PSA enforcement enabled. -func (c *ConnectHelper) setupAppNamespace(t *testing.T) { +func (c *ConnectHelper) SetupAppNamespace(t *testing.T) { if !c.UseAppNamespace { return } @@ -204,7 +204,7 @@ func (c *ConnectHelper) setupAppNamespace(t *testing.T) { func (c *ConnectHelper) CreateResolverRedirect(t *testing.T) { logger.Log(t, "creating resolver redirect") opts := c.KubectlOptsForApp(t) - c.setupAppNamespace(t) + c.SetupAppNamespace(t) kustomizeDir := "../fixtures/cases/resolver-redirect-virtualip" k8s.KubectlApplyK(t, opts, kustomizeDir) diff --git a/acceptance/framework/k8s/helpers.go b/acceptance/framework/k8s/helpers.go index 235d26d061..a6b4d1ca7c 100644 --- a/acceptance/framework/k8s/helpers.go +++ b/acceptance/framework/k8s/helpers.go @@ -139,6 +139,7 @@ func CopySecret(t *testing.T, sourceContext, destContext environment.TestContext secret.ResourceVersion = "" require.NoError(r, err) }) + secret.Namespace = destContext.KubectlOptions(t).Namespace _, err = destContext.KubernetesClient(t).CoreV1().Secrets(destContext.KubectlOptions(t).Namespace).Create(context.Background(), secret, metav1.CreateOptions{}) require.NoError(t, err) } diff --git a/acceptance/tests/wan-federation/wan_federation_test.go b/acceptance/tests/wan-federation/wan_federation_test.go index bae8e8e9da..8edc1f5d03 100644 --- a/acceptance/tests/wan-federation/wan_federation_test.go +++ b/acceptance/tests/wan-federation/wan_federation_test.go @@ -9,11 +9,11 @@ import ( "strconv" "testing" + "github.com/hashicorp/consul-k8s/acceptance/framework/connhelper" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" - "github.com/hashicorp/consul/api" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -43,10 +43,6 @@ func TestWANFederation(t *testing.T) { env := suite.Environment() cfg := suite.Config() - if cfg.UseKind { - t.Skipf("skipping wan federation tests as they currently fail on Kind even though they work on other clouds.") - } - primaryContext := env.DefaultContext(t) secondaryContext := env.Context(t, 1) @@ -86,6 +82,7 @@ func TestWANFederation(t *testing.T) { federationSecret, err := primaryContext.KubernetesClient(t).CoreV1().Secrets(primaryContext.KubectlOptions(t).Namespace).Get(context.Background(), federationSecretName, metav1.GetOptions{}) require.NoError(t, err) federationSecret.ResourceVersion = "" + federationSecret.Namespace = secondaryContext.KubectlOptions(t).Namespace _, err = secondaryContext.KubernetesClient(t).CoreV1().Secrets(secondaryContext.KubectlOptions(t).Namespace).Create(context.Background(), federationSecret, metav1.CreateOptions{}) require.NoError(t, err) @@ -161,30 +158,43 @@ func TestWANFederation(t *testing.T) { k8s.KubectlDeleteK(t, secondaryContext.KubectlOptions(t), kustomizeDir) }) + primaryHelper := connhelper.ConnectHelper{ + Secure: c.secure, + ReleaseName: releaseName, + Ctx: primaryContext, + UseAppNamespace: cfg.EnableRestrictedPSAEnforcement, + Cfg: cfg, + ConsulClient: primaryClient, + } + secondaryHelper := connhelper.ConnectHelper{ + Secure: c.secure, + ReleaseName: releaseName, + Ctx: secondaryContext, + UseAppNamespace: cfg.EnableRestrictedPSAEnforcement, + Cfg: cfg, + ConsulClient: secondaryClient, + } + + // When restricted PSA enforcement is enabled on the Consul + // namespace, deploy the test apps to a different unrestricted + // namespace because they can't run in a restricted namespace. + // This creates the app namespace only if necessary. + primaryHelper.SetupAppNamespace(t) + secondaryHelper.SetupAppNamespace(t) + // Check that we can connect services over the mesh gateways logger.Log(t, "creating static-server in dc2") - k8s.DeployKustomize(t, secondaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, secondaryHelper.KubectlOptsForApp(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") logger.Log(t, "creating static-client in dc1") - k8s.DeployKustomize(t, primaryContext.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") + k8s.DeployKustomize(t, primaryHelper.KubectlOptsForApp(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-client-multi-dc") if c.secure { - logger.Log(t, "creating intention") - _, _, err = primaryClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: "static-server", - Sources: []*api.SourceIntention{ - { - Name: StaticClientName, - Action: api.IntentionActionAllow, - }, - }, - }, nil) - require.NoError(t, err) + primaryHelper.CreateIntention(t) } logger.Log(t, "checking that connection is successful") - k8s.CheckStaticServerConnectionSuccessful(t, primaryContext.KubectlOptions(t), StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, primaryHelper.KubectlOptsForApp(t), StaticClientName, "http://localhost:1234") }) } } diff --git a/charts/consul/templates/create-federation-secret-job.yaml b/charts/consul/templates/create-federation-secret-job.yaml index bc3e0a988b..678a2af3ba 100644 --- a/charts/consul/templates/create-federation-secret-job.yaml +++ b/charts/consul/templates/create-federation-secret-job.yaml @@ -93,6 +93,7 @@ spec: containers: - name: create-federation-secret image: "{{ .Values.global.imageK8S }}" + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} env: - name: NAMESPACE valueFrom: diff --git a/charts/consul/templates/ingress-gateways-deployment.yaml b/charts/consul/templates/ingress-gateways-deployment.yaml index 328c06ee3e..c10f1549f6 100644 --- a/charts/consul/templates/ingress-gateways-deployment.yaml +++ b/charts/consul/templates/ingress-gateways-deployment.yaml @@ -175,6 +175,7 @@ spec: # ingress-gateway-init registers the ingress gateway service with Consul. - name: ingress-gateway-init image: {{ $root.Values.global.imageK8S }} + {{- include "consul.restrictedSecurityContext" $ | nindent 8 }} env: - name: NAMESPACE valueFrom: @@ -233,6 +234,7 @@ spec: containers: - name: ingress-gateway image: {{ $root.Values.global.imageConsulDataplane | quote }} + {{- include "consul.restrictedSecurityContext" $ | nindent 8 }} {{- if (default $defaults.resources .resources) }} resources: {{ toYaml (default $defaults.resources .resources) | nindent 10 }} {{- end }} diff --git a/charts/consul/templates/partition-init-job.yaml b/charts/consul/templates/partition-init-job.yaml index db73ef783b..9209f850c8 100644 --- a/charts/consul/templates/partition-init-job.yaml +++ b/charts/consul/templates/partition-init-job.yaml @@ -81,6 +81,7 @@ spec: containers: - name: partition-init-job image: {{ .Values.global.imageK8S }} + {{- include "consul.restrictedSecurityContext" . | nindent 10 }} env: {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 10 }} {{- if (and .Values.global.acls.bootstrapToken.secretName .Values.global.acls.bootstrapToken.secretKey) }} diff --git a/charts/consul/templates/sync-catalog-deployment.yaml b/charts/consul/templates/sync-catalog-deployment.yaml index e88adea533..a8793ef6f6 100644 --- a/charts/consul/templates/sync-catalog-deployment.yaml +++ b/charts/consul/templates/sync-catalog-deployment.yaml @@ -77,6 +77,7 @@ spec: containers: - name: sync-catalog image: "{{ default .Values.global.imageK8S .Values.syncCatalog.image }}" + {{- include "consul.restrictedSecurityContext" . | nindent 8 }} env: {{- include "consul.consulK8sConsulServerEnvVars" . | nindent 8 }} {{- if .Values.global.acls.manageSystemACLs }} diff --git a/charts/consul/templates/terminating-gateways-deployment.yaml b/charts/consul/templates/terminating-gateways-deployment.yaml index fdf2c17d05..9433e44bc9 100644 --- a/charts/consul/templates/terminating-gateways-deployment.yaml +++ b/charts/consul/templates/terminating-gateways-deployment.yaml @@ -160,6 +160,7 @@ spec: # terminating-gateway-init registers the terminating gateway service with Consul. - name: terminating-gateway-init image: {{ $root.Values.global.imageK8S }} + {{- include "consul.restrictedSecurityContext" $ | nindent 10 }} env: - name: NAMESPACE valueFrom: @@ -218,6 +219,7 @@ spec: containers: - name: terminating-gateway image: {{ $root.Values.global.imageConsulDataplane | quote }} + {{- include "consul.restrictedSecurityContext" $ | nindent 10 }} volumeMounts: - name: consul-service mountPath: /consul/service From f3d099cf52625058e8fa6dffd938e6c02fce0b37 Mon Sep 17 00:00:00 2001 From: Nathan Coleman Date: Wed, 9 Aug 2023 15:41:43 -0400 Subject: [PATCH 108/120] NET-4413 Implement translation + validation of TLS options (#2711) * Implement validation of TLS options * Use constants for annotation keys * Add changelog entry * Implement TLS options translation * Update changelog entry * Add unit test coverage for TLS option validation * Code review feedback --- .changelog/2711.txt | 3 + control-plane/api-gateway/binding/result.go | 6 +- .../api-gateway/binding/validation.go | 124 +++++++++++++++--- .../api-gateway/binding/validation_test.go | 41 ++++++ control-plane/api-gateway/common/constants.go | 5 + .../api-gateway/common/translation.go | 12 ++ .../api-gateway/common/translation_test.go | 22 ++++ 7 files changed, 194 insertions(+), 19 deletions(-) create mode 100644 .changelog/2711.txt diff --git a/.changelog/2711.txt b/.changelog/2711.txt new file mode 100644 index 0000000000..abb0b7e4fb --- /dev/null +++ b/.changelog/2711.txt @@ -0,0 +1,3 @@ +```release-note:feature +api-gateway: translate and validate TLS configuration options, including min/max version and cipher suites, setting Gateway status appropriately +``` diff --git a/control-plane/api-gateway/binding/result.go b/control-plane/api-gateway/binding/result.go index 1953d4836c..e6c0760e7a 100644 --- a/control-plane/api-gateway/binding/result.go +++ b/control-plane/api-gateway/binding/result.go @@ -241,7 +241,11 @@ var ( // Below is where any custom generic listener validation errors should go. // We map anything under here to a custom ListenerConditionReason of Invalid on // an Accepted status type. - errListenerNoTLSPassthrough = errors.New("TLS passthrough is not supported") + errListenerNoTLSPassthrough = errors.New("TLS passthrough is not supported") + errListenerTLSCipherSuiteNotConfigurable = errors.New("tls_min_version does not allow tls_cipher_suites configuration") + errListenerUnsupportedTLSCipherSuite = errors.New("unsupported cipher suite in tls_cipher_suites") + errListenerUnsupportedTLSMaxVersion = errors.New("unsupported tls_max_version") + errListenerUnsupportedTLSMinVersion = errors.New("unsupported tls_min_version") // This custom listener validation error is used to differentiate between an errListenerPortUnavailable because of // direct port conflicts defined by the user (two listeners on the same port) vs a port conflict because we map diff --git a/control-plane/api-gateway/binding/validation.go b/control-plane/api-gateway/binding/validation.go index d5a97499ca..6029c10b24 100644 --- a/control-plane/api-gateway/binding/validation.go +++ b/control-plane/api-gateway/binding/validation.go @@ -41,6 +41,45 @@ var ( gwv1beta1.Kind("HTTPRoute"): {}, gwv1beta1.Kind("TCPRoute"): {}, } + + allSupportedTLSVersions = map[string]struct{}{ + "TLS_AUTO": {}, + "TLSv1_0": {}, + "TLSv1_1": {}, + "TLSv1_2": {}, + "TLSv1_3": {}, + } + + allTLSVersionsWithConfigurableCipherSuites = map[string]struct{}{ + // Remove "" and "TLS_AUTO" if Envoy ever sets TLS 1.3 as default minimum + "": {}, + "TLS_AUTO": {}, + "TLSv1_0": {}, + "TLSv1_1": {}, + "TLSv1_2": {}, + } + + allSupportedTLSCipherSuites = map[string]struct{}{ + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256": {}, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256": {}, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256": {}, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": {}, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384": {}, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384": {}, + + // NOTE: the following cipher suites are currently supported by Envoy + // but have been identified as insecure and are pending removal + // https://github.com/envoyproxy/envoy/issues/5399 + "TLS_RSA_WITH_AES_128_GCM_SHA256": {}, + "TLS_RSA_WITH_AES_128_CBC_SHA": {}, + "TLS_RSA_WITH_AES_256_GCM_SHA384": {}, + "TLS_RSA_WITH_AES_256_CBC_SHA": {}, + // https://github.com/envoyproxy/envoy/issues/5400 + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA": {}, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA": {}, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA": {}, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA": {}, + } ) // validateRefs validates backend references for a route, determining whether or @@ -167,43 +206,92 @@ func (m mergedListeners) validateHostname(index int, listener gwv1beta1.Listener // validateTLS validates that the TLS configuration for a given listener is valid and that // the certificates that it references exist. func validateTLS(gateway gwv1beta1.Gateway, tls *gwv1beta1.GatewayTLSConfig, resources *common.ResourceMap) (error, error) { - namespace := gateway.Namespace - + // If there's no TLS, there's nothing to validate if tls == nil { return nil, nil } - var err error + // Validate the certificate references and then return any error + // alongside any TLS configuration error that we find below. + refsErr := validateCertificateRefs(gateway, tls.CertificateRefs, resources) + + if tls.Mode != nil && *tls.Mode == gwv1beta1.TLSModePassthrough { + return errListenerNoTLSPassthrough, refsErr + } + + if err := validateTLSOptions(tls.Options); err != nil { + return err, refsErr + } + + return nil, refsErr +} - for _, cert := range tls.CertificateRefs { - // break on the first error +func validateCertificateRefs(gateway gwv1beta1.Gateway, refs []gwv1beta1.SecretObjectReference, resources *common.ResourceMap) error { + for _, cert := range refs { + // Verify that the reference has a group and kind that we support if !common.NilOrEqual(cert.Group, "") || !common.NilOrEqual(cert.Kind, common.KindSecret) { - err = errListenerInvalidCertificateRef_NotSupported - break + return errListenerInvalidCertificateRef_NotSupported } + // Verify that the reference is within the namespace or, + // if cross-namespace, that it's allowed by a ReferenceGrant if !resources.GatewayCanReferenceSecret(gateway, cert) { - err = errRefNotPermitted - break + return errRefNotPermitted } - key := common.IndexedNamespacedNameWithDefault(cert.Name, cert.Namespace, namespace) + // Verify that the referenced resource actually exists + key := common.IndexedNamespacedNameWithDefault(cert.Name, cert.Namespace, gateway.Namespace) secret := resources.Certificate(key) - if secret == nil { - err = errListenerInvalidCertificateRef_NotFound - break + return errListenerInvalidCertificateRef_NotFound } - err = validateCertificateData(*secret) + // Verify that the referenced resource contains the data shape that we expect + if err := validateCertificateData(*secret); err != nil { + return err + } } - if tls.Mode != nil && *tls.Mode == gwv1beta1.TLSModePassthrough { - return errListenerNoTLSPassthrough, err + return nil +} + +func validateTLSOptions(options map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue) error { + if options == nil { + return nil + } + + tlsMinVersionValue := string(options[common.TLSMinVersionAnnotationKey]) + if tlsMinVersionValue != "" { + if _, supported := allSupportedTLSVersions[tlsMinVersionValue]; !supported { + return errListenerUnsupportedTLSMinVersion + } + } + + tlsMaxVersionValue := string(options[common.TLSMaxVersionAnnotationKey]) + if tlsMaxVersionValue != "" { + if _, supported := allSupportedTLSVersions[tlsMaxVersionValue]; !supported { + return errListenerUnsupportedTLSMaxVersion + } } - // TODO: validate tls options - return nil, err + tlsCipherSuitesValue := string(options[common.TLSCipherSuitesAnnotationKey]) + if tlsCipherSuitesValue != "" { + // If a minimum TLS version is configured, verify that it supports configuring cipher suites + if tlsMinVersionValue != "" { + if _, supported := allTLSVersionsWithConfigurableCipherSuites[tlsMinVersionValue]; !supported { + return errListenerTLSCipherSuiteNotConfigurable + } + } + + for _, tlsCipherSuiteValue := range strings.Split(tlsCipherSuitesValue, ",") { + tlsCipherSuite := strings.TrimSpace(tlsCipherSuiteValue) + if _, supported := allSupportedTLSCipherSuites[tlsCipherSuite]; !supported { + return errListenerUnsupportedTLSCipherSuite + } + } + } + + return nil } func validateCertificateData(secret corev1.Secret) error { diff --git a/control-plane/api-gateway/binding/validation_test.go b/control-plane/api-gateway/binding/validation_test.go index 10cdf851c3..1f2b143387 100644 --- a/control-plane/api-gateway/binding/validation_test.go +++ b/control-plane/api-gateway/binding/validation_test.go @@ -510,6 +510,47 @@ func TestValidateTLS(t *testing.T) { expectedResolvedRefsErr: nil, expectedAcceptedErr: nil, }, + "invalid cipher suite": { + gateway: gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), + tls: &gwv1beta1.GatewayTLSConfig{ + Options: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + common.TLSCipherSuitesAnnotationKey: "invalid", + }, + }, + certificates: nil, + expectedAcceptedErr: errListenerUnsupportedTLSCipherSuite, + }, + "cipher suite not configurable": { + gateway: gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), + tls: &gwv1beta1.GatewayTLSConfig{ + Options: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + common.TLSMinVersionAnnotationKey: "TLSv1_3", + common.TLSCipherSuitesAnnotationKey: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + }, + }, + certificates: nil, + expectedAcceptedErr: errListenerTLSCipherSuiteNotConfigurable, + }, + "invalid max version": { + gateway: gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), + tls: &gwv1beta1.GatewayTLSConfig{ + Options: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + common.TLSMaxVersionAnnotationKey: "invalid", + }, + }, + certificates: nil, + expectedAcceptedErr: errListenerUnsupportedTLSMaxVersion, + }, + "invalid min version": { + gateway: gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), + tls: &gwv1beta1.GatewayTLSConfig{ + Options: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + common.TLSMinVersionAnnotationKey: "invalid", + }, + }, + certificates: nil, + expectedAcceptedErr: errListenerUnsupportedTLSMinVersion, + }, } { t.Run(name, func(t *testing.T) { resources := common.NewResourceMap(common.ResourceTranslator{}, NewReferenceValidator(tt.grants), logrtest.NewTestLogger(t)) diff --git a/control-plane/api-gateway/common/constants.go b/control-plane/api-gateway/common/constants.go index c1ec0685a4..04701662b7 100644 --- a/control-plane/api-gateway/common/constants.go +++ b/control-plane/api-gateway/common/constants.go @@ -7,4 +7,9 @@ const ( GatewayClassControllerName = "consul.hashicorp.com/gateway-controller" AnnotationGatewayClassConfig = "consul.hashicorp.com/gateway-class-config" + + // The following annotation keys are used in the v1beta1.GatewayTLSConfig's Options on a v1beta1.Listener. + TLSCipherSuitesAnnotationKey = "api-gateway.consul.hashicorp.com/tls_cipher_suites" + TLSMaxVersionAnnotationKey = "api-gateway.consul.hashicorp.com/tls_max_version" + TLSMinVersionAnnotationKey = "api-gateway.consul.hashicorp.com/tls_min_version" ) diff --git a/control-plane/api-gateway/common/translation.go b/control-plane/api-gateway/common/translation.go index 2f66749c94..9303540e82 100644 --- a/control-plane/api-gateway/common/translation.go +++ b/control-plane/api-gateway/common/translation.go @@ -85,8 +85,17 @@ func (t ResourceTranslator) toAPIGatewayListener(gateway gwv1beta1.Gateway, list namespace := gateway.Namespace var certificates []api.ResourceReference + var cipherSuites []string + var maxVersion, minVersion string if listener.TLS != nil { + cipherSuitesVal := string(listener.TLS.Options[TLSCipherSuitesAnnotationKey]) + if cipherSuitesVal != "" { + cipherSuites = strings.Split(cipherSuitesVal, ",") + } + maxVersion = string(listener.TLS.Options[TLSMaxVersionAnnotationKey]) + minVersion = string(listener.TLS.Options[TLSMinVersionAnnotationKey]) + for _, ref := range listener.TLS.CertificateRefs { if !resources.GatewayCanReferenceSecret(gateway, ref) { return api.APIGatewayListener{}, false @@ -116,6 +125,9 @@ func (t ResourceTranslator) toAPIGatewayListener(gateway gwv1beta1.Gateway, list Protocol: listenerProtocolMap[strings.ToLower(string(listener.Protocol))], TLS: api.APIGatewayTLSConfiguration{ Certificates: certificates, + CipherSuites: cipherSuites, + MaxVersion: maxVersion, + MinVersion: minVersion, }, }, true } diff --git a/control-plane/api-gateway/common/translation_test.go b/control-plane/api-gateway/common/translation_test.go index daa89a698f..e8caad76ed 100644 --- a/control-plane/api-gateway/common/translation_test.go +++ b/control-plane/api-gateway/common/translation_test.go @@ -11,6 +11,7 @@ import ( "encoding/pem" "fmt" "math/big" + "strings" "testing" "time" @@ -134,6 +135,9 @@ func TestTranslator_ToAPIGateway(t *testing.T) { listenerOneCertK8sNamespace := "one-cert-ns" listenerOneCertConsulNamespace := "one-cert-ns" listenerOneCert := generateTestCertificate(t, "one-cert-ns", "one-cert") + listenerOneMaxVersion := "TLSv1_2" + listenerOneMinVersion := "TLSv1_3" + listenerOneCipherSuites := []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256"} // listener one status listenerOneLastTransmissionTime := time.Now() @@ -157,6 +161,7 @@ func TestTranslator_ToAPIGateway(t *testing.T) { annotations map[string]string expectedGWName string listenerOneK8sCertRefs []gwv1beta1.SecretObjectReference + listenerOneTLSOptions map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue }{ "gw name": { annotations: make(map[string]string), @@ -167,6 +172,11 @@ func TestTranslator_ToAPIGateway(t *testing.T) { Namespace: PointerTo(gwv1beta1.Namespace(listenerOneCertK8sNamespace)), }, }, + listenerOneTLSOptions: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + TLSMaxVersionAnnotationKey: gwv1beta1.AnnotationValue(listenerOneMaxVersion), + TLSMinVersionAnnotationKey: gwv1beta1.AnnotationValue(listenerOneMinVersion), + TLSCipherSuitesAnnotationKey: gwv1beta1.AnnotationValue(strings.Join(listenerOneCipherSuites, ",")), + }, }, "when k8s has certs that are not referenced in consul": { annotations: make(map[string]string), @@ -181,6 +191,11 @@ func TestTranslator_ToAPIGateway(t *testing.T) { Namespace: PointerTo(gwv1beta1.Namespace(listenerOneCertK8sNamespace)), }, }, + listenerOneTLSOptions: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + TLSMaxVersionAnnotationKey: gwv1beta1.AnnotationValue(listenerOneMaxVersion), + TLSMinVersionAnnotationKey: gwv1beta1.AnnotationValue(listenerOneMinVersion), + TLSCipherSuitesAnnotationKey: gwv1beta1.AnnotationValue(strings.Join(listenerOneCipherSuites, ",")), + }, }, } @@ -207,6 +222,7 @@ func TestTranslator_ToAPIGateway(t *testing.T) { Protocol: gwv1beta1.ProtocolType(listenerOneProtocol), TLS: &gwv1beta1.GatewayTLSConfig{ CertificateRefs: tc.listenerOneK8sCertRefs, + Options: tc.listenerOneTLSOptions, }, }, { @@ -288,6 +304,9 @@ func TestTranslator_ToAPIGateway(t *testing.T) { Namespace: listenerOneCertConsulNamespace, }, }, + CipherSuites: listenerOneCipherSuites, + MaxVersion: listenerOneMaxVersion, + MinVersion: listenerOneMinVersion, }, }, { @@ -303,6 +322,9 @@ func TestTranslator_ToAPIGateway(t *testing.T) { Namespace: listenerTwoCertConsulNamespace, }, }, + CipherSuites: nil, + MaxVersion: "", + MinVersion: "", }, }, }, From a287fce551affef7d358394032e8997f79220c8b Mon Sep 17 00:00:00 2001 From: John Maguire Date: Wed, 9 Aug 2023 16:03:14 -0400 Subject: [PATCH 109/120] NET-4993 JWT auth basic acceptance test (#2706) * JWT auth basic acceptance test * Update to run only in enterprise mode, update comment to be correct * Remove usage of `testing.t` in retry block * Fixed last `t` in retry block in tests * Update acceptance/tests/api-gateway/api_gateway_test.go Co-authored-by: Nathan Coleman * Update acceptance/tests/api-gateway/api_gateway_test.go Co-authored-by: Nathan Coleman * Updating filenames for gw jwt cases and adding message about why this test is skipped --------- Co-authored-by: Nathan Coleman --- .../tests/api-gateway/api_gateway_test.go | 253 +++++++++++++++++- .../api-gateways/jwt-auth/api-gateway.yaml | 37 +++ .../api-gateways/jwt-auth/gateway-policy.yaml | 24 ++ .../api-gateways/jwt-auth/httproute-auth.yaml | 32 +++ .../api-gateways/jwt-auth/httproute.yaml | 19 ++ .../api-gateways/jwt-auth/jwt-provider.yaml | 9 + .../jwt-auth/jwt-route-filter.yaml | 12 + .../api-gateways/jwt-auth/kustomization.yaml | 12 + 8 files changed, 397 insertions(+), 1 deletion(-) create mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/api-gateway.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/gateway-policy.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute-auth.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-provider.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-route-filter.yaml create mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/kustomization.yaml diff --git a/acceptance/tests/api-gateway/api_gateway_test.go b/acceptance/tests/api-gateway/api_gateway_test.go index 721bbf2527..df4a097b7e 100644 --- a/acceptance/tests/api-gateway/api_gateway_test.go +++ b/acceptance/tests/api-gateway/api_gateway_test.go @@ -126,7 +126,7 @@ func TestAPIGateway_Basic(t *testing.T) { // On startup, the controller can take upwards of 1m to perform // leader election so we may need to wait a long time for - // the reconcile loop to run (hence the 1m timeout here). + // the reconcile loop to run (hence the timeout here). var gatewayAddress string counter := &retry.Counter{Count: 120, Wait: 2 * time.Second} retry.RunWith(counter, t, func(r *retry.R) { @@ -288,6 +288,257 @@ func TestAPIGateway_Basic(t *testing.T) { } } +func TestAPIGateway_JWTAuth_Basic(t *testing.T) { + t.Skip("skipping this test until GW JWT auth is complete") + ctx := suite.Environment().DefaultContext(t) + cfg := suite.Config() + + if !cfg.EnableEnterprise { + t.Skipf("skipping this test because -enable-enterprise is not set") + } + + helmValues := map[string]string{ + "connectInject.enabled": "true", + "connectInject.consulNamespaces.mirroringK8S": "true", + "global.acls.manageSystemACLs": "true", // acls must be enabled for JWT auth to take place + "global.tls.enabled": "true", + "global.logLevel": "trace", + } + + releaseName := helpers.RandomName() + consulCluster := consul.NewHelmCluster(t, helmValues, ctx, cfg, releaseName) + + consulCluster.Create(t) + + // Override the default proxy config settings for this test + consulClient, _ := consulCluster.SetupConsulClient(t, true) + _, _, err := consulClient.ConfigEntries().Set(&api.ProxyConfigEntry{ + Kind: api.ProxyDefaults, + Name: api.ProxyConfigGlobal, + Config: map[string]interface{}{ + "protocol": "http", + }, + }, nil) + require.NoError(t, err) + + logger.Log(t, "creating api-gateway resources") + out, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-k", "../fixtures/cases/api-gateways/jwt-auth") + require.NoError(t, err, out) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + // Ignore errors here because if the test ran as expected + // the custom resources will have been deleted. + k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-k", "../fixtures/cases/api-gateways/jwt-auth") + }) + + // Create certificate secret, we do this separately since + // applying the secret will make an invalid certificate that breaks other tests + logger.Log(t, "creating certificate secret") + out, err = k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-f", "../fixtures/bases/api-gateway/certificate.yaml") + require.NoError(t, err, out) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + // Ignore errors here because if the test ran as expected + // the custom resources will have been deleted. + k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-f", "../fixtures/bases/api-gateway/certificate.yaml") + }) + + // patch certificate with data + logger.Log(t, "patching certificate secret with generated data") + certificate := generateCertificate(t, nil, "gateway.test.local") + k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "secret", "certificate", "-p", fmt.Sprintf(`{"data":{"tls.crt":"%s","tls.key":"%s"}}`, base64.StdEncoding.EncodeToString(certificate.CertPEM), base64.StdEncoding.EncodeToString(certificate.PrivateKeyPEM)), "--type=merge") + + // We use the static-client pod so that we can make calls to the api gateway + // via kubectl exec without needing a route into the cluster from the test machine. + logger.Log(t, "creating static-client pod") + k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") + + k8s.RunKubectl(t, ctx.KubectlOptions(t), "wait", "--for=condition=available", "--timeout=5m", fmt.Sprintf("deploy/%s", "static-server")) + // Grab a kubernetes client so that we can verify binding + // behavior prior to issuing requests through the gateway. + k8sClient := ctx.ControllerRuntimeClient(t) + + // On startup, the controller can take upwards of 1m to perform + // leader election so we may need to wait a long time for + // the reconcile loop to run (hence the 2m timeout here). + var ( + gatewayAddress string + gatewayClass gwv1beta1.GatewayClass + httpRoute gwv1beta1.HTTPRoute + httpRouteAuth gwv1beta1.HTTPRoute + ) + + counter := &retry.Counter{Count: 60, Wait: 2 * time.Second} + retry.RunWith(counter, t, func(r *retry.R) { + var gateway gwv1beta1.Gateway + err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: "default"}, &gateway) + require.NoError(r, err) + + // check our finalizers + require.Len(r, gateway.Finalizers, 1) + require.EqualValues(r, gatewayFinalizer, gateway.Finalizers[0]) + + // check our statuses + checkStatusCondition(r, gateway.Status.Conditions, trueCondition("Accepted", "Accepted")) + checkStatusCondition(r, gateway.Status.Conditions, trueCondition("ConsulAccepted", "Accepted")) + require.Len(r, gateway.Status.Listeners, 4) + + require.EqualValues(r, 1, gateway.Status.Listeners[0].AttachedRoutes) + checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, trueCondition("Accepted", "Accepted")) + checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, falseCondition("Conflicted", "NoConflicts")) + checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) + require.EqualValues(r, 1, gateway.Status.Listeners[1].AttachedRoutes) + checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, trueCondition("Accepted", "Accepted")) + checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, falseCondition("Conflicted", "NoConflicts")) + checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) + + // check that we have an address to use + require.Len(r, gateway.Status.Addresses, 1) + // now we know we have an address, set it so we can use it + gatewayAddress = gateway.Status.Addresses[0].Value + + // gateway class checks + err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway-class"}, &gatewayClass) + require.NoError(r, err) + + // check our finalizers + require.Len(r, gatewayClass.Finalizers, 1) + require.EqualValues(r, gatewayClassFinalizer, gatewayClass.Finalizers[0]) + + // http route checks + err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "http-route", Namespace: "default"}, &httpRoute) + require.NoError(r, err) + + // http route checks + err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "http-route-auth", Namespace: "default"}, &httpRouteAuth) + require.NoError(r, err) + + // check our finalizers + require.Len(r, httpRoute.Finalizers, 1) + require.EqualValues(r, gatewayFinalizer, httpRoute.Finalizers[0]) + + // check parent status + require.Len(r, httpRoute.Status.Parents, 1) + require.EqualValues(r, gatewayClassControllerName, httpRoute.Status.Parents[0].ControllerName) + require.EqualValues(r, "gateway", httpRoute.Status.Parents[0].ParentRef.Name) + checkStatusCondition(r, httpRoute.Status.Parents[0].Conditions, trueCondition("Accepted", "Accepted")) + checkStatusCondition(r, httpRoute.Status.Parents[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) + checkStatusCondition(r, httpRoute.Status.Parents[0].Conditions, trueCondition("ConsulAccepted", "Accepted")) + + // check our finalizers + require.Len(r, httpRouteAuth.Finalizers, 1) + require.EqualValues(r, gatewayFinalizer, httpRouteAuth.Finalizers[0]) + + // check parent status + require.Len(r, httpRouteAuth.Status.Parents, 1) + require.EqualValues(r, gatewayClassControllerName, httpRouteAuth.Status.Parents[0].ControllerName) + require.EqualValues(r, "gateway", httpRouteAuth.Status.Parents[0].ParentRef.Name) + checkStatusCondition(r, httpRouteAuth.Status.Parents[0].Conditions, trueCondition("Accepted", "Accepted")) + checkStatusCondition(r, httpRouteAuth.Status.Parents[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) + checkStatusCondition(r, httpRouteAuth.Status.Parents[0].Conditions, trueCondition("ConsulAccepted", "Accepted")) + }) + + // check that the Consul entries were created + entry, _, err := consulClient.ConfigEntries().Get(api.APIGateway, "gateway", nil) + require.NoError(t, err) + gateway := entry.(*api.APIGatewayConfigEntry) + + entry, _, err = consulClient.ConfigEntries().Get(api.HTTPRoute, "http-route", nil) + require.NoError(t, err) + consulHTTPRoute := entry.(*api.HTTPRouteConfigEntry) + + entry, _, err = consulClient.ConfigEntries().Get(api.HTTPRoute, "http-route-auth", nil) + require.NoError(t, err) + consulHTTPRouteAuth := entry.(*api.HTTPRouteConfigEntry) + + // now check the gateway status conditions + checkConsulStatusCondition(t, gateway.Status.Conditions, trueConsulCondition("Accepted", "Accepted")) + + // and the route status conditions + checkConsulStatusCondition(t, consulHTTPRoute.Status.Conditions, trueConsulCondition("Bound", "Bound")) + checkConsulStatusCondition(t, consulHTTPRouteAuth.Status.Conditions, trueConsulCondition("Bound", "Bound")) + + // finally we check that we can actually route to the service(s) via the gateway + k8sOptions := ctx.KubectlOptions(t) + targetHTTPAddress := fmt.Sprintf("http://%s/v1", gatewayAddress) + targetHTTPAddressAdmin := fmt.Sprintf("http://%s:8080/admin", gatewayAddress) + targetHTTPAddressPet := fmt.Sprintf("http://%s:8080/pet", gatewayAddress) + // valid JWT token with role of "doctor" + doctorToken := "eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzI1NiIsImtpZCI6IkMtRTFuQ2p3Z0JDLVB1R00yTzQ2N0ZSRGhLeDhBa1ZjdElTQWJvM3JpZXcifQ.eyJpc3MiOiJsb2NhbCIsInJvbGUiOiJkb2N0b3IifQ.FfgpzjMf8Evh6K-fJ1cLXklfIXOm-vojVbWlPPbGVFtzxZ9hxMxoyAY_G8i36SfGrpUlp-RJ6ohMvprMrEgyRgbenu7u5kkm5iGHW-zpMus4izXRxPELBcpWOGF105HIssT2NYRstXieNR8EVzvGfLdvR0GW8ttEERgseqGvuAfdb4-aNYsysGwUUHbsZjazA6H1rZmWqHdCLOJ2ZwFsIdckO9CadnkyTILpcPUmLYyUVJdtlLGOySb0GG8c_dPML_IR5jSXCSUZt6S2JBNBNBdqukrlqpA-fIaaWft0dbWVMhv8DqPC8znult8dKvLZ1qXeU0itsqqJUyE16ihJjw" + // valid JWT token with role of "pet" + petToken := "eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzI1NiIsImtpZCI6IkMtRTFuQ2p3Z0JDLVB1R00yTzQ2N0ZSRGhLeDhBa1ZjdElTQWJvM3JpZXcifQ.eyJpc3MiOiJsb2NhbCIsInJvbGUiOiJwZXQifQ.l94rJayGGTMB426HwEw5ipSjaIHjm-UWDHiBAlB_Slmi814AxAfl_0AdRwSz67UDnkoygKbvPpR5xUB03JCXNshLZuKLegWsBeQg_OJYvZGmFagl5NglBFvH7Jbta4e1eQoAxZI6Xyy1jHbu7jFBjQPVnK8EaRvWoW8Pe8a8rp_5xhub0pomhvRF6Pm5kAS4cMnxvqpVc5Oo5nO7ws_SmoNnbt2Ok14k23Zx5E2EWmGStOfbgFsdbhVbepB2DMzqv1j8jvBbwa_OxCwc_7pEOthOOxRV6L3ZjgbRSB4GumlXAOCBYXD1cRLgrMSrWB1GkefAKu8PV0Ho1px6sI9Evg" + + // check that intentions keep our connection from happening + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddress) + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddressAdmin) + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", doctorToken, targetHTTPAddressAdmin) + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", petToken, targetHTTPAddressAdmin) + + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddressPet) + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", doctorToken, targetHTTPAddressPet) + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", petToken, targetHTTPAddressPet) + + // Now we create the allow intention. + _, _, err = consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ + Kind: api.ServiceIntentions, + Name: "static-server", + Sources: []*api.SourceIntention{ + { + Name: "gateway", + Action: api.IntentionActionAllow, + }, + }, + }, nil) + require.NoError(t, err) + + _, _, err = consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ + Kind: api.ServiceIntentions, + Name: "static-server-protected", + Sources: []*api.SourceIntention{ + { + Name: "gateway", + Action: api.IntentionActionAllow, + }, + }, + }, nil) + require.NoError(t, err) + + // Test that we can make a call to the api gateway + logger.Log(t, "trying calls to api gateway http") + k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, targetHTTPAddress) + + // ensure that overrides -> route extension -> default by making a request to the admin route with a JWT that has an issuer of "local" and a "role" of "doctor" + // we can see that: + // * the "iss" verification in the gateway override takes precedence over the "iss" verification in the route filter + // * the "role" verification in the route extension takes precedence over the "role" verification in the gateway default + // should fail because we're missing JWT + logger.Log(t, "trying calls to api gateway /admin should fail without JWT token") + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddressAdmin) + + // should fail because we use the token with the wrong role and correct issuer + logger.Log(t, "trying calls to api gateway /admin should fail with wrong role") + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", petToken, targetHTTPAddressAdmin) + + // will succeed because we use the token with the correct role and the correct issuer + logger.Log(t, "trying calls to api gateway /admin should succeed with JWT token with correct role") + k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, "-H", doctorToken, targetHTTPAddressAdmin) + + // ensure that overrides -> route extension -> default by making a request to the admin route with a JWT that has an issuer of "local" and a "role" of "pet" + // the route does not define + // we can see that: + // * the "iss" verification in the gateway override takes precedence over the "iss" verification in the route filter + // * the "role" verification in the route extension takes precedence over the "role" verification in the gateway default + // should fail because we're missing JWT + logger.Log(t, "trying calls to api gateway /pet should fail without JWT token") + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddressPet) + + // should fail because we use the token with the wrong role and correct issuer + logger.Log(t, "trying calls to api gateway /pet should fail with wrong role") + k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", doctorToken, targetHTTPAddressPet) + + // will succeed because we use the token with the correct role and the correct issuer + logger.Log(t, "trying calls to api gateway /pet should succeed with JWT token with correct role") + k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, "-H", petToken, targetHTTPAddressPet) +} + func checkStatusCondition(t require.TestingT, conditions []metav1.Condition, toCheck metav1.Condition) { for _, c := range conditions { if c.Type == toCheck.Type { diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/api-gateway.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/api-gateway.yaml new file mode 100644 index 0000000000..bef7e96f12 --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/api-gateway.yaml @@ -0,0 +1,37 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: Gateway +metadata: + name: gateway +spec: + gatewayClassName: gateway-class + listeners: + - protocol: HTTP + port: 8080 + name: http-auth + allowedRoutes: + namespaces: + from: "All" + - protocol: HTTP + port: 80 + name: http + allowedRoutes: + namespaces: + from: "All" + - protocol: TCP + port: 81 + name: tcp + allowedRoutes: + namespaces: + from: "All" + - protocol: HTTPS + port: 443 + name: https + tls: + certificateRefs: + - name: "certificate" + allowedRoutes: + namespaces: + from: "All" diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/gateway-policy.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/gateway-policy.yaml new file mode 100644 index 0000000000..8e47d75062 --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/gateway-policy.yaml @@ -0,0 +1,24 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: ConsulGatewayPolicy +metadata: + name: my-policy +spec: + targetRef: + name: gateway + kind: Gateway + group: gateway.networking.kuberenetes.io + sectionName: http + override: + Providers: + - Provider: "local" + VerifyClaims: + - Path: + - "iss" + Value: "local" + default: + Providers: + - Provider: "local" + VerifyClaims: + - Path: + - "iss" + Value: "local" diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute-auth.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute-auth.yaml new file mode 100644 index 0000000000..4963277c55 --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute-auth.yaml @@ -0,0 +1,32 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-route-auth +spec: + parentRefs: + - name: gateway + sectionName: http-auth + rules: + - matches: + - path: + type: PathPrefix + value: "/admin" + backendRefs: + - name: static-server + port: 80 + filters: + - type: ExtensionRef + extensionRef: + group: consul.hashicorp.com + kind: HTTPRouteAuthFilter + name: route-jwt-auth-filter + - matches: + - path: + type: PathPrefix + value: "/pet" + backendRefs: + - name: static-server + port: 80 diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute.yaml new file mode 100644 index 0000000000..52e206a91e --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute.yaml @@ -0,0 +1,19 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: gateway.networking.k8s.io/v1beta1 +kind: HTTPRoute +metadata: + name: http-route +spec: + parentRefs: + - name: gateway + sectionName: http + rules: + - matches: + - path: + type: PathPrefix + value: "/v1" + backendRefs: + - name: static-server + port: 80 diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-provider.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-provider.yaml new file mode 100644 index 0000000000..37eb034d3c --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-provider.yaml @@ -0,0 +1,9 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: JWTProvider +metadata: + name: local +spec: + issuer: local + jsonWebKeySet: + local: + jwks: "ewogICAgImtleXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAicCI6ICI5TTlWSVhJR0hpR3FlTnhseEJ2V0xFV09oUFh3dXhXZUpod01uM3dGdG9STEtfZmF6VWxjWEc1cUViLTdpMXo3VmlPUWVZRnh6WUZYTS1pbVU3OVFRa1dTVUVSazR2dHZuc2R5UnpUSnVPc3A0ZUhuWFVMSHJPOU51NkJ5bC1VeVprMzFvSnFGeGllM0pHQXlRLUM2OVF2NVFkVjFZV0hfVDkyTzk4d1hYZGMiLAogICAgICAgICAgICAia3R5IjogIlJTQSIsCiAgICAgICAgICAgICJxIjogInFIVnZBb3h0ckgxUTVza25veXNMMkhvbC1ubnU3ZlM3Mjg4clRGdE9jeG9Jb29nWXBKVTljemxwcjctSlo2bjc0TUViVHBBMHRkSUR5TEtQQ0xIN3JKTFRrZzBDZVZNQWpmY01zdkRUcWdFOHNBWE42bzd2ZjYya2hwcExYOHVCU3JxSHkyV1JhZXJsbDROU09hcmRGSkQ2MWhHSVF2cEpXRk4xazFTV3pWcyIsCiAgICAgICAgICAgICJkIjogIlp3elJsVklRZkg5ekZ6d1hOZ2hEMHhkZVctalBCbmRkWnJNZ0wwQ2JjeXZZYlg2X1c0ajlhM1dmYWpobmI2bTFILW9CWjRMczVmNXNRVTB2ZFJ2ZG1laFItUG43aWNRcUdURFNKUTYtdWVtNm15UVRWaEo2UmZiM0lINVJ2VDJTOXUzcVFDZWFadWN3aXFoZ1RCbFhnOWFfV0pwVHJYNFhPQ3JCR1ZsTng3Z2JETVJOamNEN0FnRkZ3S2p2TEZVdDRLTkZmdEJqaFF0TDFLQ2VwblNmamtvRm1RUTVlX3RSS2ozX2U1V3pNSkJkekpQejNkR2YxZEk3OF9wYmJFbmFMcWhqNWg0WUx2UU5JUUhVcURYSGx4ZDc1Qlh3aFJReE1nUDRfd1EwTFk2cVRKNGFDa2Q0RDJBTUtqMzJqeVFiVTRKTE9jQjFNMnZBRWFyc2NTU3l0USIsCiAgICAgICAgICAgICJlIjogIkFRQUIiLAogICAgICAgICAgICAidXNlIjogInNpZyIsCiAgICAgICAgICAgICJraWQiOiAiQy1FMW5DandnQkMtUHVHTTJPNDY3RlJEaEt4OEFrVmN0SVNBYm8zcmlldyIsCiAgICAgICAgICAgICJxaSI6ICJ0N2VOQjhQV21xVHdKREZLQlZKZExrZnJJT2drMFJ4MnREODBGNHB5cjhmNzRuNGlVWXFmWG1haVZtbGx2c2FlT3JlNHlIczQ4UE45NVZsZlVvS3Z6ZEJFaDNZTDFINGZTOGlYYXNzNGJiVnVuWHR4U0hMZFFPYUNZYUplSmhBbGMyUWQ4elR0NFFQWk9yRWVWLVJTYU0tN095ekkwUWtSSF9tcmk1YmRrOXMiLAogICAgICAgICAgICAiZHAiOiAiYnBLckQtVXhrRENDal81MFZLU0NFeE1Ec1Zob2VBZm1tNjMxb1o5aDhUTkZ4TUU1YVptbUJ2VzBJUG9wMm1PUF9qTW9FVWxfUG1RYUlBOEgtVEdqTFp2QTMxSlZBeFN3TU5aQzdwaVFPRjYzVnhneTZUTzlmb1hENVdndC1oLUNxU1N6T2V3eFdmUWNTMmpMcTA3NUFxOTYwTnA2SHhjbE8weUdRN1JDSlpjIiwKICAgICAgICAgICAgImFsZyI6ICJQUzI1NiIsCiAgICAgICAgICAgICJkcSI6ICJpdVZveGwwckFKSEM1c2JzbTZpZWQ3c2ZIVXIwS2Rja0hiVFBLb0lPU1BFcU5YaXBlT3BrWkdEdU55NWlDTXNyRnNHaDFrRW9kTkhZdE40ay1USm5KSDliV296SGdXbGloNnN2R1V0Zi1raFMxWC16ckxaMTJudzlyNDRBbjllWG54bjFaVXMxZm5OakltM3dtZ083algyTWxIeVlNVUZVd0RMd09xNEFPUWsiLAogICAgICAgICAgICAibiI6ICJvUmhjeUREdmp3NFZ4SHRRNTZhRDlNSmRTaWhWSk1nTHd1b2FCQVhhc0RjVDNEWVZjcENlVGxDMVBPdzdPNW1Ec2ZSWVFtcGpoendyRDVZWU8yeDE4REl4czdyNTNJdFMxRy1ybnQxQ1diVE9fUzFJT01DR2xxYzh5VWJnLUhSUkRETXQyb2V3TjJoRGtxYlBKVFJNbXpjRkpNMHRpTm1RZVVMcWViZEVYaWVUblJMT1BkMWg2ZmJycVNLS01mSXlIbGZ1WXFQc1VWSEdkMVBESGljZ3NMazFtZDhtYTNIS1hWM0hJdzZrdUV6R0hQb1gxNHo4YWF6RFFZWndUR3ZxVGlPLUdRUlVDZUJueVo4bVhyWnRmSjNqVk83UUhXcEx3MlM1VDVwVTRwcE0xQXppWTFxUDVfY3ZpOTNZT2Zrb09PalRTX3V3RENZWGFxWjB5bTJHYlEiCiAgICAgICAgfQogICAgXQp9Cg==" diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-route-filter.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-route-filter.yaml new file mode 100644 index 0000000000..e0a3128bed --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-route-filter.yaml @@ -0,0 +1,12 @@ +apiVersion: consul.hashicorp.com/v1alpha1 +kind: HTTPRouteAuthFilter +metadata: + name: example-route-jwt-filter +spec: + type: JWT + JWTProviders: + - Provider: "local" + VerifyClaims: + - Path: + - "role" + Value: "doctor" diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/kustomization.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/kustomization.yaml new file mode 100644 index 0000000000..3dc38a090c --- /dev/null +++ b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/kustomization.yaml @@ -0,0 +1,12 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../bases/api-gateway + - ../../static-server-inject + - ./httproute.yaml + - ./jwt-provider.yaml + +patchesStrategicMerge: + - httproute-no-auth.yaml + - api-gateway.yaml From a86533b117bbda4711bbcb0947aab86a45e8f230 Mon Sep 17 00:00:00 2001 From: Michael Zalimeni Date: Thu, 10 Aug 2023 11:28:50 -0400 Subject: [PATCH 110/120] [NET-5217] Apply K8s node locality to services and sidecars (#2748) Apply K8s node locality to services and sidecars Locality-aware routing is based on proxy locality rather than the proxied service. Ensure we propagate locality to both when registering services. --- .changelog/2748.txt | 3 +++ .../controllers/endpoints/endpoints_controller.go | 2 ++ .../controllers/endpoints/endpoints_controller_test.go | 5 +++++ 3 files changed, 10 insertions(+) create mode 100644 .changelog/2748.txt diff --git a/.changelog/2748.txt b/.changelog/2748.txt new file mode 100644 index 0000000000..2a8c922d13 --- /dev/null +++ b/.changelog/2748.txt @@ -0,0 +1,3 @@ +```release-note:bug +control-plane: Set locality on sidecar proxies in addition to services when registering with connect-inject. +``` diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go index cdf56b187f..3f139c2662 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go @@ -535,6 +535,8 @@ func (r *Controller) createServiceRegistrations(pod corev1.Pod, serviceEndpoints Namespace: consulNS, Proxy: proxyConfig, Tags: tags, + // Sidecar locality (not proxied service locality) is used for locality-aware routing. + Locality: locality, } // A user can enable/disable tproxy for an entire namespace. diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go index 477be49e9f..2cec69dd0a 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go @@ -2021,6 +2021,10 @@ func TestReconcileCreateEndpoint(t *testing.T) { "envoy_telemetry_collector_bind_socket_dir": "/consul/connect-inject", }, }, + ServiceLocality: &api.Locality{ + Region: "us-west-1", + Zone: "us-west-1a", + }, ServiceMeta: map[string]string{ "name": "abc", "version": "2", @@ -2225,6 +2229,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { require.Equal(t, tt.expectedProxySvcInstances[i].ServicePort, instance.ServicePort) require.Equal(t, tt.expectedProxySvcInstances[i].ServiceMeta, instance.ServiceMeta) require.Equal(t, tt.expectedProxySvcInstances[i].ServiceTags, instance.ServiceTags) + require.Equal(t, tt.expectedProxySvcInstances[i].ServiceLocality, instance.ServiceLocality) if tt.nodeMeta != nil { require.Equal(t, tt.expectedProxySvcInstances[i].NodeMeta, instance.NodeMeta) } From 0100fa4f066a184de8ae11976ef70b5afa85fe39 Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Fri, 11 Aug 2023 10:46:44 -0400 Subject: [PATCH 111/120] Adds changelog for release of 1.1.4 (#2754) --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d60f91b67..aa47db462e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ +## 1.1.4 (Aug 10, 2023) + +SECURITY: + +* Upgrade to use Go 1.20.6 and `x/net/http` 0.12.0. + This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2642](https://github.com/hashicorp/consul-k8s/issues/2642)] +* Upgrade to use Go 1.20.7 and `x/net` 0.13.0. + This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) + and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2710](https://github.com/hashicorp/consul-k8s/issues/2710)] + +IMPROVEMENTS: + +* Add support to provide the logLevel flag via helm for multiple low level components. Introduces the following fields +1. `global.acls.logLevel` +2. `global.tls.logLevel` +3. `global.federation.logLevel` +4. `global.gossipEncryption.logLevel` +5. `server.logLevel` +6. `client.logLevel` +7. `meshGateway.logLevel` +8. `ingressGateways.logLevel` +9. `terminatingGateways.logLevel` +10. `telemetryCollector.logLevel` [[GH-2302](https://github.com/hashicorp/consul-k8s/issues/2302)] +* control-plane: increase timeout after login for ACL replication to 60 seconds [[GH-2656](https://github.com/hashicorp/consul-k8s/issues/2656)] +* helm: adds values for `securityContext` and `annotations` on TLS and ACL init/cleanup jobs. [[GH-2525](https://github.com/hashicorp/consul-k8s/issues/2525)] +* helm: do not set container securityContexts by default on OpenShift < 4.11 [[GH-2678](https://github.com/hashicorp/consul-k8s/issues/2678)] +* helm: set container securityContexts to match the `restricted` Pod Security Standards policy to support running Consul in a namespace with restricted PSA enforcement enabled [[GH-2572](https://github.com/hashicorp/consul-k8s/issues/2572)] + +BUG FIXES: + +* control-plane: fix bug in endpoints controller when deregistering services from consul when a node is deleted. [[GH-2571](https://github.com/hashicorp/consul-k8s/issues/2571)] +* helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. [[GH-2652](https://github.com/hashicorp/consul-k8s/issues/2652)] +* helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. [[GH-2687](https://github.com/hashicorp/consul-k8s/issues/2687)] + ## 0.49.8 (July 12, 2023) IMPROVEMENTS: From 6e98cf90d890d74371214fc5b52628e4bfe96cbc Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Fri, 11 Aug 2023 14:29:29 -0400 Subject: [PATCH 112/120] Set privileged to false unless on OpenShift without CNI (#2755) * Set privileged to false unless on OpenShift without CNI --- .changelog/2755.txt | 3 + .../connect-inject/webhook/container_init.go | 10 +++- .../webhook/container_init_test.go | 57 +++++++++++++++---- 3 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 .changelog/2755.txt diff --git a/.changelog/2755.txt b/.changelog/2755.txt new file mode 100644 index 0000000000..1d8cf20360 --- /dev/null +++ b/.changelog/2755.txt @@ -0,0 +1,3 @@ +```release-note:bug +control-plane: When using transparent proxy or CNI, reduced required permissions by setting privileged to false. Privileged must be true when using OpenShift without CNI. +``` diff --git a/control-plane/connect-inject/webhook/container_init.go b/control-plane/connect-inject/webhook/container_init.go index f180de88a3..88962f771e 100644 --- a/control-plane/connect-inject/webhook/container_init.go +++ b/control-plane/connect-inject/webhook/container_init.go @@ -223,6 +223,12 @@ func (w *MeshWebhook) containerInit(namespace corev1.Namespace, pod corev1.Pod, }) } + // OpenShift without CNI is the only environment where privileged must be true. + privileged := false + if w.EnableOpenShift && !w.EnableCNI { + privileged = true + } + if tproxyEnabled { if !w.EnableCNI { // Set redirect traffic config for the container so that we can apply iptables rules. @@ -243,7 +249,7 @@ func (w *MeshWebhook) containerInit(namespace corev1.Namespace, pod corev1.Pod, RunAsGroup: pointer.Int64(rootUserAndGroupID), // RunAsNonRoot overrides any setting in the Pod so that we can still run as root here as required. RunAsNonRoot: pointer.Bool(false), - Privileged: pointer.Bool(true), + Privileged: pointer.Bool(privileged), Capabilities: &corev1.Capabilities{ Add: []corev1.Capability{netAdminCapability}, }, @@ -253,7 +259,7 @@ func (w *MeshWebhook) containerInit(namespace corev1.Namespace, pod corev1.Pod, RunAsUser: pointer.Int64(initContainersUserAndGroupID), RunAsGroup: pointer.Int64(initContainersUserAndGroupID), RunAsNonRoot: pointer.Bool(true), - Privileged: pointer.Bool(false), + Privileged: pointer.Bool(privileged), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, diff --git a/control-plane/connect-inject/webhook/container_init_test.go b/control-plane/connect-inject/webhook/container_init_test.go index fd89d7eba6..fa2a95dbf9 100644 --- a/control-plane/connect-inject/webhook/container_init_test.go +++ b/control-plane/connect-inject/webhook/container_init_test.go @@ -176,77 +176,104 @@ func TestHandlerContainerInit_transparentProxy(t *testing.T) { annotations map[string]string expTproxyEnabled bool namespaceLabel map[string]string + openShiftEnabled bool }{ - "enabled globally, ns not set, annotation not provided, cni disabled": { + "enabled globally, ns not set, annotation not provided, cni disabled, openshift disabled": { true, false, nil, true, nil, + false, }, - "enabled globally, ns not set, annotation is false, cni disabled": { + "enabled globally, ns not set, annotation is false, cni disabled, openshift disabled": { true, false, map[string]string{constants.KeyTransparentProxy: "false"}, false, nil, + false, }, - "enabled globally, ns not set, annotation is true, cni disabled": { + "enabled globally, ns not set, annotation is true, cni disabled, openshift disabled": { true, false, map[string]string{constants.KeyTransparentProxy: "true"}, true, nil, + false, }, - "disabled globally, ns not set, annotation not provided, cni disabled": { + "disabled globally, ns not set, annotation not provided, cni disabled, openshift disabled": { false, false, nil, false, nil, + false, }, - "disabled globally, ns not set, annotation is false, cni disabled": { + "disabled globally, ns not set, annotation is false, cni disabled, openshift disabled": { false, false, map[string]string{constants.KeyTransparentProxy: "false"}, false, nil, + false, }, - "disabled globally, ns not set, annotation is true, cni disabled": { + "disabled globally, ns not set, annotation is true, cni disabled, openshift disabled": { false, false, map[string]string{constants.KeyTransparentProxy: "true"}, true, nil, + false, }, - "disabled globally, ns enabled, annotation not set, cni disabled": { + "disabled globally, ns enabled, annotation not set, cni disabled, openshift disabled": { false, false, nil, true, map[string]string{constants.KeyTransparentProxy: "true"}, + false, }, - "enabled globally, ns disabled, annotation not set, cni disabled": { + "enabled globally, ns disabled, annotation not set, cni disabled, openshift disabled": { true, false, nil, false, map[string]string{constants.KeyTransparentProxy: "false"}, + false, }, - "disabled globally, ns enabled, annotation not set, cni enabled": { + "disabled globally, ns enabled, annotation not set, cni enabled, openshift disabled": { false, true, nil, false, map[string]string{constants.KeyTransparentProxy: "true"}, + false, }, - "enabled globally, ns not set, annotation not set, cni enabled": { + "enabled globally, ns not set, annotation not set, cni enabled, openshift disabled": { + true, + true, + nil, + false, + nil, + false, + }, + "enabled globally, ns not set, annotation not set, cni enabled, openshift enabled": { true, true, nil, false, nil, + true, + }, + "enabled globally, ns not set, annotation not set, cni disabled, openshift enabled": { + true, + false, + nil, + true, + nil, + true, }, } for name, c := range cases { @@ -255,17 +282,23 @@ func TestHandlerContainerInit_transparentProxy(t *testing.T) { EnableTransparentProxy: c.globalEnabled, EnableCNI: c.cniEnabled, ConsulConfig: &consul.Config{HTTPPort: 8500}, + EnableOpenShift: c.openShiftEnabled, } pod := minimal() pod.Annotations = c.annotations + privileged := false + if c.openShiftEnabled && !c.cniEnabled { + privileged = true + } + var expectedSecurityContext *corev1.SecurityContext if c.cniEnabled { expectedSecurityContext = &corev1.SecurityContext{ RunAsUser: pointer.Int64(initContainersUserAndGroupID), RunAsGroup: pointer.Int64(initContainersUserAndGroupID), RunAsNonRoot: pointer.Bool(true), - Privileged: pointer.Bool(false), + Privileged: pointer.Bool(privileged), Capabilities: &corev1.Capabilities{ Drop: []corev1.Capability{"ALL"}, }, @@ -275,7 +308,7 @@ func TestHandlerContainerInit_transparentProxy(t *testing.T) { RunAsUser: pointer.Int64(0), RunAsGroup: pointer.Int64(0), RunAsNonRoot: pointer.Bool(false), - Privileged: pointer.Bool(true), + Privileged: pointer.Bool(privileged), Capabilities: &corev1.Capabilities{ Add: []corev1.Capability{netAdminCapability}, }, From b57b9369c61ee60b4f2a48a1bf0abf7a71cd8e8a Mon Sep 17 00:00:00 2001 From: Curt Bushko Date: Fri, 11 Aug 2023 16:21:09 -0400 Subject: [PATCH 113/120] Update consul-enterprise-version script to add -ent (#2756) --- .../build-support/scripts/consul-enterprise-version.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/control-plane/build-support/scripts/consul-enterprise-version.sh b/control-plane/build-support/scripts/consul-enterprise-version.sh index 6b48bb4678..37df85dfc5 100755 --- a/control-plane/build-support/scripts/consul-enterprise-version.sh +++ b/control-plane/build-support/scripts/consul-enterprise-version.sh @@ -4,8 +4,10 @@ FILE=$1 VERSION=$(yq .global.image $FILE) -if [[ !"${VERSION}" == *"consul:"* ]]; then +if [[ !"${VERSION}" == *"hashicorppreview/consul:"* ]]; then VERSION=$(echo ${VERSION} | sed "s/consul:/consul-enterprise:/g") +elif [[ !"${VERSION}" == *"hashicorp/consul:"* ]]; then + VERSION=$(echo ${VERSION} | sed "s/consul:/consul-enterprise:/g" | sed "s/$/-ent/g") fi echo "${VERSION}" From 1968df4fdc7cc54b782f450f1c5fb4f569aa9322 Mon Sep 17 00:00:00 2001 From: Michael Wilkerson <62034708+wilkermichael@users.noreply.github.com> Date: Fri, 11 Aug 2023 15:35:14 -0700 Subject: [PATCH 114/120] Automate the k8s sameness tests add peering (#2725) * added fixtures * removed fixtures - intentions only gets added now if acls are enabled - payment-service-resolver is only for locality aware which isn't in scope for this PR * updated sameness tests to include peering - refactored with some helper functions for members (now TestClusters) - made names more uniform, tend more towards the cluster-01-a/cluster-02-a/etc. nomenclature * added 4 clusters to cni make target * disable proxy lifecycle --- Makefile | 4 + .../kustomization.yaml | 0 .../cluster-01-a-default-ns/sameness.yaml | 14 + .../kustomization.yaml | 5 + .../cluster-01-b-default-ns/sameness.yaml | 14 + .../kustomization.yaml | 5 + .../sameness.yaml | 7 +- .../kustomization.yaml | 5 + .../cluster-03-a-default-ns/sameness.yaml | 14 + .../sameness/override-ns/intentions.yaml | 15 - .../sameness/override-ns/kustomization.yaml | 2 - .../override-ns/payment-service-resolver.yaml | 16 - .../cluster-01-a-dialer/kustomization.yaml | 6 + .../peering-dialer-cluster-02-a.yaml | 13 + .../peering-dialer-cluster-03-a.yaml | 13 + .../cluster-01-b-dialer/kustomization.yaml | 6 + .../peering-dialer-cluster-02-a.yaml | 13 + .../peering-dialer-cluster-03-a.yaml | 13 + .../cluster-02-a-acceptor/kustomization.yaml | 6 + .../peering-acceptor-cluster-01-a.yaml | 13 + .../peering-acceptor-cluster-01-b.yaml | 13 + .../cluster-02-a-dialer/kustomization.yaml | 5 + .../peering-dialer-cluster-03-a.yaml | 13 + .../cluster-03-a-acceptor/kustomization.yaml | 7 + .../peering-acceptor-cluster-01-a.yaml | 13 + .../peering-acceptor-cluster-01-b.yaml | 13 + .../peering-acceptor-cluster-02-a.yaml | 13 + .../peering/{ => mesh}/kustomization.yaml | 0 .../sameness/peering/{ => mesh}/mesh.yaml | 0 .../cluster-01-a-acceptor/kustomization.yaml | 8 + .../sameness/cluster-01-a-acceptor/patch.yaml | 13 + .../cluster-01-b-acceptor/kustomization.yaml | 8 + .../sameness/cluster-01-b-acceptor/patch.yaml | 13 + .../cluster-02-a-acceptor/kustomization.yaml | 8 + .../sameness/cluster-02-a-acceptor/patch.yaml | 13 + .../cluster-03-a-acceptor/kustomization.yaml | 8 + .../sameness/cluster-03-a-acceptor/patch.yaml | 13 + .../ap1-partition/patch.yaml | 4 +- .../default-partition/patch.yaml | 4 +- .../kustomization.yaml | 0 .../{partition => ap1-partition}/patch.yaml | 0 .../kustomization.yaml | 0 .../{default => default-partition}/patch.yaml | 0 .../kustomization.yaml | 0 .../{default => dc1-default}/patch.yaml | 0 .../kustomization.yaml | 0 .../{partition => dc1-partition}/patch.yaml | 0 .../static-server/dc2/kustomization.yaml | 8 + .../sameness/static-server/dc2/patch.yaml | 23 + .../static-server/dc3/kustomization.yaml | 8 + .../sameness/static-server/dc3/patch.yaml | 23 + acceptance/tests/sameness/main_test.go | 2 +- acceptance/tests/sameness/sameness_test.go | 578 +++++++++++++----- 53 files changed, 812 insertions(+), 183 deletions(-) rename acceptance/tests/fixtures/bases/sameness/{default-ns => cluster-01-a-default-ns}/kustomization.yaml (100%) create mode 100644 acceptance/tests/fixtures/bases/sameness/cluster-01-a-default-ns/sameness.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/cluster-01-b-default-ns/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/cluster-01-b-default-ns/sameness.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/cluster-02-a-default-ns/kustomization.yaml rename acceptance/tests/fixtures/bases/sameness/{default-ns => cluster-02-a-default-ns}/sameness.yaml (73%) create mode 100644 acceptance/tests/fixtures/bases/sameness/cluster-03-a-default-ns/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/cluster-03-a-default-ns/sameness.yaml delete mode 100644 acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml delete mode 100644 acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/peering-dialer-cluster-02-a.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/peering-dialer-cluster-03-a.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/peering-dialer-cluster-02-a.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/peering-dialer-cluster-03-a.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/peering-acceptor-cluster-01-a.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/peering-acceptor-cluster-01-b.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-dialer/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-dialer/peering-dialer-cluster-03-a.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/kustomization.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-01-a.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-01-b.yaml create mode 100644 acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-02-a.yaml rename acceptance/tests/fixtures/bases/sameness/peering/{ => mesh}/kustomization.yaml (100%) rename acceptance/tests/fixtures/bases/sameness/peering/{ => mesh}/mesh.yaml (100%) create mode 100644 acceptance/tests/fixtures/cases/sameness/cluster-01-a-acceptor/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/cluster-01-a-acceptor/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/cluster-01-b-acceptor/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/cluster-01-b-acceptor/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/cluster-02-a-acceptor/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/cluster-02-a-acceptor/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/cluster-03-a-acceptor/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/cluster-03-a-acceptor/patch.yaml rename acceptance/tests/fixtures/cases/sameness/static-client/{default => ap1-partition}/kustomization.yaml (100%) rename acceptance/tests/fixtures/cases/sameness/static-client/{partition => ap1-partition}/patch.yaml (100%) rename acceptance/tests/fixtures/cases/sameness/static-client/{partition => default-partition}/kustomization.yaml (100%) rename acceptance/tests/fixtures/cases/sameness/static-client/{default => default-partition}/patch.yaml (100%) rename acceptance/tests/fixtures/cases/sameness/static-server/{default => dc1-default}/kustomization.yaml (100%) rename acceptance/tests/fixtures/cases/sameness/static-server/{default => dc1-default}/patch.yaml (100%) rename acceptance/tests/fixtures/cases/sameness/static-server/{partition => dc1-partition}/kustomization.yaml (100%) rename acceptance/tests/fixtures/cases/sameness/static-server/{partition => dc1-partition}/patch.yaml (100%) create mode 100644 acceptance/tests/fixtures/cases/sameness/static-server/dc2/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-server/dc2/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-server/dc3/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-server/dc3/patch.yaml diff --git a/Makefile b/Makefile index e9a02a01b3..866a37fbfc 100644 --- a/Makefile +++ b/Makefile @@ -143,6 +143,10 @@ kind-cni: kind-delete make kind-cni-calico kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc2 --image $(KIND_NODE_IMAGE) make kind-cni-calico + kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc3 --image $(KIND_NODE_IMAGE) + make kind-cni-calico + kind create cluster --config=$(CURDIR)/acceptance/framework/environment/cni-kind/kind.config --name dc4 --image $(KIND_NODE_IMAGE) + make kind-cni-calico # Helper target for doing local acceptance testing kind: kind-delete diff --git a/acceptance/tests/fixtures/bases/sameness/default-ns/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/cluster-01-a-default-ns/kustomization.yaml similarity index 100% rename from acceptance/tests/fixtures/bases/sameness/default-ns/kustomization.yaml rename to acceptance/tests/fixtures/bases/sameness/cluster-01-a-default-ns/kustomization.yaml diff --git a/acceptance/tests/fixtures/bases/sameness/cluster-01-a-default-ns/sameness.yaml b/acceptance/tests/fixtures/bases/sameness/cluster-01-a-default-ns/sameness.yaml new file mode 100644 index 0000000000..9c43bb505f --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/cluster-01-a-default-ns/sameness.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: SamenessGroup +metadata: + name: group-01 +spec: + defaultForFailover: true + members: + - partition: default + - partition: ap1 + - peer: cluster-02-a + - peer: cluster-03-a \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/cluster-01-b-default-ns/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/cluster-01-b-default-ns/kustomization.yaml new file mode 100644 index 0000000000..3f9d23c28a --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/cluster-01-b-default-ns/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - sameness.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/cluster-01-b-default-ns/sameness.yaml b/acceptance/tests/fixtures/bases/sameness/cluster-01-b-default-ns/sameness.yaml new file mode 100644 index 0000000000..bf83338243 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/cluster-01-b-default-ns/sameness.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: SamenessGroup +metadata: + name: group-01 +spec: + defaultForFailover: true + members: + - partition: ap1 + - partition: default + - peer: cluster-02-a + - peer: cluster-03-a \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/cluster-02-a-default-ns/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/cluster-02-a-default-ns/kustomization.yaml new file mode 100644 index 0000000000..3f9d23c28a --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/cluster-02-a-default-ns/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - sameness.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml b/acceptance/tests/fixtures/bases/sameness/cluster-02-a-default-ns/sameness.yaml similarity index 73% rename from acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml rename to acceptance/tests/fixtures/bases/sameness/cluster-02-a-default-ns/sameness.yaml index 4d27ed72ae..2ed466585b 100644 --- a/acceptance/tests/fixtures/bases/sameness/default-ns/sameness.yaml +++ b/acceptance/tests/fixtures/bases/sameness/cluster-02-a-default-ns/sameness.yaml @@ -4,12 +4,11 @@ apiVersion: consul.hashicorp.com/v1alpha1 kind: SamenessGroup metadata: - name: mine + name: group-01 spec: + defaultForFailover: true members: - partition: default - - partition: ap1 - peer: cluster-01-a - peer: cluster-01-b - - peer: cluster-02-a - - peer: cluster-03-a + - peer: cluster-03-a \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/cluster-03-a-default-ns/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/cluster-03-a-default-ns/kustomization.yaml new file mode 100644 index 0000000000..3f9d23c28a --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/cluster-03-a-default-ns/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - sameness.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/cluster-03-a-default-ns/sameness.yaml b/acceptance/tests/fixtures/bases/sameness/cluster-03-a-default-ns/sameness.yaml new file mode 100644 index 0000000000..83a3c1e71a --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/cluster-03-a-default-ns/sameness.yaml @@ -0,0 +1,14 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: SamenessGroup +metadata: + name: group-01 +spec: + defaultForFailover: true + members: + - partition: default + - peer: cluster-01-a + - peer: cluster-01-b + - peer: cluster-02-a \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml deleted file mode 100644 index ae075c85e4..0000000000 --- a/acceptance/tests/fixtures/bases/sameness/override-ns/intentions.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ServiceIntentions -metadata: - name: static-server -spec: - destination: - name: static-server - sources: - - name: static-client - namespace: ns1 - samenessGroup: mine - action: allow diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/kustomization.yaml index adfd1c827b..0646179949 100644 --- a/acceptance/tests/fixtures/bases/sameness/override-ns/kustomization.yaml +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/kustomization.yaml @@ -2,6 +2,4 @@ # SPDX-License-Identifier: MPL-2.0 resources: - - intentions.yaml - - payment-service-resolver.yaml - service-defaults.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml deleted file mode 100644 index 4257294c6b..0000000000 --- a/acceptance/tests/fixtures/bases/sameness/override-ns/payment-service-resolver.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ServiceResolver -metadata: - name: static-server -spec: - connectTimeout: 15s - failover: - '*': - samenessGroup: mine - policy: - mode: order-by-locality - regions: - - us-west-2 diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/kustomization.yaml new file mode 100644 index 0000000000..cf214eac6c --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/kustomization.yaml @@ -0,0 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - peering-dialer-cluster-02-a.yaml + - peering-dialer-cluster-03-a.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/peering-dialer-cluster-02-a.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/peering-dialer-cluster-02-a.yaml new file mode 100644 index 0000000000..d4c51553f3 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/peering-dialer-cluster-02-a.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringDialer +metadata: + name: cluster-02-a +spec: + peer: + secret: + name: "cluster-02-a-cluster-01-a-peering-token" + key: "data" + backend: "kubernetes" diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/peering-dialer-cluster-03-a.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/peering-dialer-cluster-03-a.yaml new file mode 100644 index 0000000000..e6f9f9a6c9 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-a-dialer/peering-dialer-cluster-03-a.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringDialer +metadata: + name: cluster-03-a +spec: + peer: + secret: + name: "cluster-03-a-cluster-01-a-peering-token" + key: "data" + backend: "kubernetes" diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/kustomization.yaml new file mode 100644 index 0000000000..cf214eac6c --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/kustomization.yaml @@ -0,0 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - peering-dialer-cluster-02-a.yaml + - peering-dialer-cluster-03-a.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/peering-dialer-cluster-02-a.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/peering-dialer-cluster-02-a.yaml new file mode 100644 index 0000000000..8f0f7064df --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/peering-dialer-cluster-02-a.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringDialer +metadata: + name: cluster-02-a +spec: + peer: + secret: + name: "cluster-02-a-cluster-01-b-peering-token" + key: "data" + backend: "kubernetes" diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/peering-dialer-cluster-03-a.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/peering-dialer-cluster-03-a.yaml new file mode 100644 index 0000000000..27cdd27ff8 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-01-b-dialer/peering-dialer-cluster-03-a.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringDialer +metadata: + name: cluster-03-a +spec: + peer: + secret: + name: "cluster-03-a-cluster-01-b-peering-token" + key: "data" + backend: "kubernetes" diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/kustomization.yaml new file mode 100644 index 0000000000..4c485ee633 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/kustomization.yaml @@ -0,0 +1,6 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - peering-acceptor-cluster-01-a.yaml + - peering-acceptor-cluster-01-b.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/peering-acceptor-cluster-01-a.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/peering-acceptor-cluster-01-a.yaml new file mode 100644 index 0000000000..b20b61328f --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/peering-acceptor-cluster-01-a.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: cluster-01-a +spec: + peer: + secret: + name: "cluster-02-a-cluster-01-a-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/peering-acceptor-cluster-01-b.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/peering-acceptor-cluster-01-b.yaml new file mode 100644 index 0000000000..c2d5c21b37 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-acceptor/peering-acceptor-cluster-01-b.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: cluster-01-b +spec: + peer: + secret: + name: "cluster-02-a-cluster-01-b-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-dialer/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-dialer/kustomization.yaml new file mode 100644 index 0000000000..c90eab30cc --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-dialer/kustomization.yaml @@ -0,0 +1,5 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - peering-dialer-cluster-03-a.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-dialer/peering-dialer-cluster-03-a.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-dialer/peering-dialer-cluster-03-a.yaml new file mode 100644 index 0000000000..80518a04c2 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-02-a-dialer/peering-dialer-cluster-03-a.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringDialer +metadata: + name: cluster-03-a +spec: + peer: + secret: + name: "cluster-03-a-cluster-02-a-peering-token" + key: "data" + backend: "kubernetes" diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/kustomization.yaml new file mode 100644 index 0000000000..543a846805 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/kustomization.yaml @@ -0,0 +1,7 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - peering-acceptor-cluster-01-a.yaml + - peering-acceptor-cluster-01-b.yaml + - peering-acceptor-cluster-02-a.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-01-a.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-01-a.yaml new file mode 100644 index 0000000000..06c87e15a6 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-01-a.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: cluster-01-a +spec: + peer: + secret: + name: "cluster-03-a-cluster-01-a-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-01-b.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-01-b.yaml new file mode 100644 index 0000000000..0a835ecef5 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-01-b.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: cluster-01-b +spec: + peer: + secret: + name: "cluster-03-a-cluster-01-b-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-02-a.yaml b/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-02-a.yaml new file mode 100644 index 0000000000..e60ea8b083 --- /dev/null +++ b/acceptance/tests/fixtures/bases/sameness/peering/cluster-03-a-acceptor/peering-acceptor-cluster-02-a.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: cluster-02-a +spec: + peer: + secret: + name: "cluster-03-a-cluster-02-a-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/peering/kustomization.yaml b/acceptance/tests/fixtures/bases/sameness/peering/mesh/kustomization.yaml similarity index 100% rename from acceptance/tests/fixtures/bases/sameness/peering/kustomization.yaml rename to acceptance/tests/fixtures/bases/sameness/peering/mesh/kustomization.yaml diff --git a/acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml b/acceptance/tests/fixtures/bases/sameness/peering/mesh/mesh.yaml similarity index 100% rename from acceptance/tests/fixtures/bases/sameness/peering/mesh.yaml rename to acceptance/tests/fixtures/bases/sameness/peering/mesh/mesh.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/cluster-01-a-acceptor/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/cluster-01-a-acceptor/kustomization.yaml new file mode 100644 index 0000000000..30ddacd76c --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/cluster-01-a-acceptor/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../bases/sameness/peering/acceptor + +patchesStrategicMerge: + - patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/cluster-01-a-acceptor/patch.yaml b/acceptance/tests/fixtures/cases/sameness/cluster-01-a-acceptor/patch.yaml new file mode 100644 index 0000000000..2746eeef2e --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/cluster-01-a-acceptor/patch.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: acceptor +spec: + peer: + secret: + name: "cluster-01-a-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/cluster-01-b-acceptor/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/cluster-01-b-acceptor/kustomization.yaml new file mode 100644 index 0000000000..30ddacd76c --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/cluster-01-b-acceptor/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../bases/sameness/peering/acceptor + +patchesStrategicMerge: + - patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/cluster-01-b-acceptor/patch.yaml b/acceptance/tests/fixtures/cases/sameness/cluster-01-b-acceptor/patch.yaml new file mode 100644 index 0000000000..9ca48dad0c --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/cluster-01-b-acceptor/patch.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: acceptor +spec: + peer: + secret: + name: "cluster-01-b-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/cluster-02-a-acceptor/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/cluster-02-a-acceptor/kustomization.yaml new file mode 100644 index 0000000000..30ddacd76c --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/cluster-02-a-acceptor/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../bases/sameness/peering/acceptor + +patchesStrategicMerge: + - patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/cluster-02-a-acceptor/patch.yaml b/acceptance/tests/fixtures/cases/sameness/cluster-02-a-acceptor/patch.yaml new file mode 100644 index 0000000000..4343992f8f --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/cluster-02-a-acceptor/patch.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: acceptor +spec: + peer: + secret: + name: "cluster-02-a-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/cluster-03-a-acceptor/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/cluster-03-a-acceptor/kustomization.yaml new file mode 100644 index 0000000000..6a54cd6eab --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/cluster-03-a-acceptor/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../bases/sameness/peering/acceptor + +patchesStrategicMerge: +- patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/cluster-03-a-acceptor/patch.yaml b/acceptance/tests/fixtures/cases/sameness/cluster-03-a-acceptor/patch.yaml new file mode 100644 index 0000000000..1cd49b79d7 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/cluster-03-a-acceptor/patch.yaml @@ -0,0 +1,13 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: consul.hashicorp.com/v1alpha1 +kind: PeeringAcceptor +metadata: + name: acceptor +spec: + peer: + secret: + name: "cluster-03-a-peering-token" + key: "data" + backend: "kubernetes" \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/patch.yaml b/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/patch.yaml index d71e8211ba..22fa816fed 100644 --- a/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/patch.yaml +++ b/acceptance/tests/fixtures/cases/sameness/exported-services/ap1-partition/patch.yaml @@ -10,7 +10,7 @@ spec: - name: static-server namespace: ns2 consumers: - - samenessGroup: mine + - samenessGroup: group-01 - name: mesh-gateway consumers: - - samenessGroup: mine + - samenessGroup: group-01 diff --git a/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/patch.yaml b/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/patch.yaml index 9bb440637e..4dbacf99e1 100644 --- a/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/patch.yaml +++ b/acceptance/tests/fixtures/cases/sameness/exported-services/default-partition/patch.yaml @@ -10,7 +10,7 @@ spec: - name: static-server namespace: ns2 consumers: - - samenessGroup: mine + - samenessGroup: group-01 - name: mesh-gateway consumers: - - samenessGroup: mine + - samenessGroup: group-01 diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/default/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition/kustomization.yaml similarity index 100% rename from acceptance/tests/fixtures/cases/sameness/static-client/default/kustomization.yaml rename to acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition/kustomization.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/partition/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition/patch.yaml similarity index 100% rename from acceptance/tests/fixtures/cases/sameness/static-client/partition/patch.yaml rename to acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition/patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/partition/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/default-partition/kustomization.yaml similarity index 100% rename from acceptance/tests/fixtures/cases/sameness/static-client/partition/kustomization.yaml rename to acceptance/tests/fixtures/cases/sameness/static-client/default-partition/kustomization.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/default/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/default-partition/patch.yaml similarity index 100% rename from acceptance/tests/fixtures/cases/sameness/static-client/default/patch.yaml rename to acceptance/tests/fixtures/cases/sameness/static-client/default-partition/patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/default/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/dc1-default/kustomization.yaml similarity index 100% rename from acceptance/tests/fixtures/cases/sameness/static-server/default/kustomization.yaml rename to acceptance/tests/fixtures/cases/sameness/static-server/dc1-default/kustomization.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/default/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/dc1-default/patch.yaml similarity index 100% rename from acceptance/tests/fixtures/cases/sameness/static-server/default/patch.yaml rename to acceptance/tests/fixtures/cases/sameness/static-server/dc1-default/patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/partition/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/dc1-partition/kustomization.yaml similarity index 100% rename from acceptance/tests/fixtures/cases/sameness/static-server/partition/kustomization.yaml rename to acceptance/tests/fixtures/cases/sameness/static-server/dc1-partition/kustomization.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/partition/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/dc1-partition/patch.yaml similarity index 100% rename from acceptance/tests/fixtures/cases/sameness/static-server/partition/patch.yaml rename to acceptance/tests/fixtures/cases/sameness/static-server/dc1-partition/patch.yaml diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/dc2/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/dc2/kustomization.yaml new file mode 100644 index 0000000000..c15bfe7ba7 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-server/dc2/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/static-server + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/dc2/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/dc2/patch.yaml new file mode 100644 index 0000000000..07ac3b9aa9 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-server/dc2/patch.yaml @@ -0,0 +1,23 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-server +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + spec: + containers: + - name: static-server + image: docker.mirror.hashicorp.services/hashicorp/http-echo:alpine + args: + - -text="cluster-02-a" + - -listen=:8080 + ports: + - containerPort: 8080 + name: http + serviceAccountName: static-server diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/dc3/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/dc3/kustomization.yaml new file mode 100644 index 0000000000..c15bfe7ba7 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-server/dc3/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/static-server + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-server/dc3/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-server/dc3/patch.yaml new file mode 100644 index 0000000000..135e7b14fb --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-server/dc3/patch.yaml @@ -0,0 +1,23 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-server +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + spec: + containers: + - name: static-server + image: docker.mirror.hashicorp.services/hashicorp/http-echo:alpine + args: + - -text="cluster-03-a" + - -listen=:8080 + ports: + - containerPort: 8080 + name: http + serviceAccountName: static-server diff --git a/acceptance/tests/sameness/main_test.go b/acceptance/tests/sameness/main_test.go index 67e6ee42b7..ded943c6f0 100644 --- a/acceptance/tests/sameness/main_test.go +++ b/acceptance/tests/sameness/main_test.go @@ -23,6 +23,6 @@ func TestMain(m *testing.M) { } else { fmt.Println(fmt.Sprintf("Skipping sameness tests because either -enable-multi-cluster is "+ "not set, the number of clusters did not match the expected count of %d, or --useKind is false. "+ - "Sameness acceptance tests are currently only suopported on Kind clusters", expectedNumberOfClusters)) + "Sameness acceptance tests are currently only supported on Kind clusters", expectedNumberOfClusters)) } } diff --git a/acceptance/tests/sameness/sameness_test.go b/acceptance/tests/sameness/sameness_test.go index 3971ccf27a..629b886d95 100644 --- a/acceptance/tests/sameness/sameness_test.go +++ b/acceptance/tests/sameness/sameness_test.go @@ -7,7 +7,9 @@ import ( "context" "fmt" "strconv" + "strings" "testing" + "time" terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/config" @@ -24,23 +26,32 @@ import ( ) const ( - primaryDatacenterPartition = "ap1" - primaryServerDatacenter = "dc1" - peer1Datacenter = "dc2" - peer2Datacenter = "dc3" - staticClientNamespace = "ns1" - staticServerNamespace = "ns2" - - keyPrimaryServer = "server" - keyPartition = "partition" - keyPeer1 = "peer1" - keyPeer2 = "peer2" + cluster01Partition = "ap1" + cluster01Datacenter = "dc1" + cluster02Datacenter = "dc2" + cluster03Datacenter = "dc3" + staticClientNamespace = "ns1" + staticServerNamespace = "ns2" + + keyCluster01a = "cluster-01-a" + keyCluster01b = "cluster-01-b" + keyCluster02a = "cluster-02-a" + keyCluster03a = "cluster-03-a" + + staticServerName = "static-server" + staticClientName = "static-client" staticServerDeployment = "deploy/static-server" staticClientDeployment = "deploy/static-client" - primaryServerClusterName = "cluster-01-a" - partitionClusterName = "cluster-01-b" + peerName1a = keyCluster01a + peerName1b = keyCluster01b + peerName2a = keyCluster02a + peerName3a = keyCluster03a + + samenessGroupName = "group-01" + + retryTimeout = 5 * time.Minute ) func TestFailover_Connect(t *testing.T) { @@ -127,19 +138,19 @@ func TestFailover_Connect(t *testing.T) { +-------------------------------------------+ */ - members := map[string]*member{ - keyPrimaryServer: {context: env.DefaultContext(t), hasServer: true}, - keyPartition: {context: env.Context(t, 1), hasServer: false}, - keyPeer1: {context: env.Context(t, 2), hasServer: true}, - keyPeer2: {context: env.Context(t, 3), hasServer: true}, + testClusters := clusters{ + keyCluster01a: {name: peerName1a, context: env.DefaultContext(t), hasServer: true, acceptors: []string{peerName2a, peerName3a}}, + keyCluster01b: {name: peerName1b, context: env.Context(t, 1), partition: cluster01Partition, hasServer: false, acceptors: []string{peerName2a, peerName3a}}, + keyCluster02a: {name: peerName2a, context: env.Context(t, 2), hasServer: true, acceptors: []string{peerName3a}}, + keyCluster03a: {name: peerName3a, context: env.Context(t, 3), hasServer: true}, } // Setup Namespaces. - for _, v := range members { + for _, v := range testClusters { createNamespaces(t, cfg, v.context) } - // Create the Default Cluster. + // Create the cluster-01-a. commonHelmValues := map[string]string{ "global.peering.enabled": "true", @@ -150,7 +161,7 @@ func TestFailover_Connect(t *testing.T) { "global.adminPartitions.enabled": "true", - "global.logLevel": "debug", + "global.logLevel": "warn", "global.acls.manageSystemACLs": strconv.FormatBool(c.ACLsEnabled), @@ -161,10 +172,11 @@ func TestFailover_Connect(t *testing.T) { "meshGateway.replicas": "1", "dns.enabled": "true", + "connectInject.sidecarProxy.lifecycle.defaultEnabled": "false", } defaultPartitionHelmValues := map[string]string{ - "global.datacenter": primaryServerDatacenter, + "global.datacenter": cluster01Datacenter, } // On Kind, there are no load balancers but since all clusters @@ -180,39 +192,39 @@ func TestFailover_Connect(t *testing.T) { helpers.MergeMaps(defaultPartitionHelmValues, commonHelmValues) releaseName := helpers.RandomName() - members[keyPrimaryServer].helmCluster = consul.NewHelmCluster(t, defaultPartitionHelmValues, members[keyPrimaryServer].context, cfg, releaseName) - members[keyPrimaryServer].helmCluster.Create(t) + testClusters[keyCluster01a].helmCluster = consul.NewHelmCluster(t, defaultPartitionHelmValues, testClusters[keyCluster01a].context, cfg, releaseName) + testClusters[keyCluster01a].helmCluster.Create(t) // Get the TLS CA certificate and key secret from the server cluster and apply it to the client cluster. caCertSecretName := fmt.Sprintf("%s-consul-ca-cert", releaseName) logger.Logf(t, "retrieving ca cert secret %s from the server cluster and applying to the client cluster", caCertSecretName) - k8s.CopySecret(t, members[keyPrimaryServer].context, members[keyPartition].context, caCertSecretName) + k8s.CopySecret(t, testClusters[keyCluster01a].context, testClusters[keyCluster01b].context, caCertSecretName) - // Create Secondary Partition Cluster which will apply the primary datacenter. + // Create Secondary Partition Cluster (cluster-01-b) which will apply the primary (dc1) datacenter. partitionToken := fmt.Sprintf("%s-consul-partitions-acl-token", releaseName) if c.ACLsEnabled { logger.Logf(t, "retrieving partition token secret %s from the server cluster and applying to the client cluster", partitionToken) - k8s.CopySecret(t, members[keyPrimaryServer].context, members[keyPartition].context, partitionToken) + k8s.CopySecret(t, testClusters[keyCluster01a].context, testClusters[keyCluster01b].context, partitionToken) } partitionServiceName := fmt.Sprintf("%s-consul-expose-servers", releaseName) - partitionSvcAddress := k8s.ServiceHost(t, cfg, members[keyPrimaryServer].context, partitionServiceName) + partitionSvcAddress := k8s.ServiceHost(t, cfg, testClusters[keyCluster01a].context, partitionServiceName) - k8sAuthMethodHost := k8s.KubernetesAPIServerHost(t, cfg, members[keyPartition].context) + k8sAuthMethodHost := k8s.KubernetesAPIServerHost(t, cfg, testClusters[keyCluster01b].context) secondaryPartitionHelmValues := map[string]string{ "global.enabled": "false", - "global.datacenter": primaryServerDatacenter, + "global.datacenter": cluster01Datacenter, - "global.adminPartitions.name": primaryDatacenterPartition, + "global.adminPartitions.name": cluster01Partition, "global.tls.caCert.secretName": caCertSecretName, "global.tls.caCert.secretKey": "tls.crt", "externalServers.enabled": "true", "externalServers.hosts[0]": partitionSvcAddress, - "externalServers.tlsServerName": fmt.Sprintf("server.%s.consul", primaryServerDatacenter), + "externalServers.tlsServerName": fmt.Sprintf("server.%s.consul", cluster01Datacenter), "global.server.enabled": "false", } @@ -231,12 +243,12 @@ func TestFailover_Connect(t *testing.T) { } helpers.MergeMaps(secondaryPartitionHelmValues, commonHelmValues) - members[keyPartition].helmCluster = consul.NewHelmCluster(t, secondaryPartitionHelmValues, members[keyPartition].context, cfg, releaseName) - members[keyPartition].helmCluster.Create(t) + testClusters[keyCluster01b].helmCluster = consul.NewHelmCluster(t, secondaryPartitionHelmValues, testClusters[keyCluster01b].context, cfg, releaseName) + testClusters[keyCluster01b].helmCluster.Create(t) - // Create Peer 1 Cluster. + // Create cluster-02-a Cluster. PeerOneHelmValues := map[string]string{ - "global.datacenter": peer1Datacenter, + "global.datacenter": cluster02Datacenter, } if cfg.UseKind { @@ -246,12 +258,12 @@ func TestFailover_Connect(t *testing.T) { } helpers.MergeMaps(PeerOneHelmValues, commonHelmValues) - members[keyPeer1].helmCluster = consul.NewHelmCluster(t, PeerOneHelmValues, members[keyPeer1].context, cfg, releaseName) - members[keyPeer1].helmCluster.Create(t) + testClusters[keyCluster02a].helmCluster = consul.NewHelmCluster(t, PeerOneHelmValues, testClusters[keyCluster02a].context, cfg, releaseName) + testClusters[keyCluster02a].helmCluster.Create(t) - // Create Peer 2 Cluster. + // Create cluster-03-a Cluster. PeerTwoHelmValues := map[string]string{ - "global.datacenter": peer2Datacenter, + "global.datacenter": cluster03Datacenter, } if cfg.UseKind { @@ -261,138 +273,298 @@ func TestFailover_Connect(t *testing.T) { } helpers.MergeMaps(PeerTwoHelmValues, commonHelmValues) - members[keyPeer2].helmCluster = consul.NewHelmCluster(t, PeerTwoHelmValues, members[keyPeer2].context, cfg, releaseName) - members[keyPeer2].helmCluster.Create(t) + testClusters[keyCluster03a].helmCluster = consul.NewHelmCluster(t, PeerTwoHelmValues, testClusters[keyCluster03a].context, cfg, releaseName) + testClusters[keyCluster03a].helmCluster.Create(t) // Create a ProxyDefaults resource to configure services to use the mesh // gateways and set server and client opts. - for k, v := range members { + for k, v := range testClusters { logger.Logf(t, "applying resources on %s", v.context.KubectlOptions(t).ContextName) // Client will use the client namespace. - members[k].clientOpts = &terratestk8s.KubectlOptions{ + testClusters[k].clientOpts = &terratestk8s.KubectlOptions{ ContextName: v.context.KubectlOptions(t).ContextName, ConfigPath: v.context.KubectlOptions(t).ConfigPath, Namespace: staticClientNamespace, } // Server will use the server namespace. - members[k].serverOpts = &terratestk8s.KubectlOptions{ + testClusters[k].serverOpts = &terratestk8s.KubectlOptions{ ContextName: v.context.KubectlOptions(t).ContextName, ConfigPath: v.context.KubectlOptions(t).ConfigPath, Namespace: staticServerNamespace, } // Sameness Defaults need to be applied first so that the sameness group exists. - applyResources(t, cfg, "../fixtures/bases/mesh-gateway", members[k].context.KubectlOptions(t)) - applyResources(t, cfg, "../fixtures/bases/sameness/default-ns", members[k].context.KubectlOptions(t)) - applyResources(t, cfg, "../fixtures/bases/sameness/override-ns", members[k].serverOpts) + applyResources(t, cfg, "../fixtures/bases/mesh-gateway", v.context.KubectlOptions(t)) + applyResources(t, cfg, "../fixtures/bases/sameness/override-ns", v.serverOpts) // Only assign a client if the cluster is running a Consul server. if v.hasServer { - members[k].client, _ = members[k].helmCluster.SetupConsulClient(t, c.ACLsEnabled) + testClusters[k].client, _ = testClusters[k].helmCluster.SetupConsulClient(t, c.ACLsEnabled) } } - // TODO: Add further setup for peering, right now the rest of this test will only cover Partitions - // Create static server deployments. - logger.Log(t, "creating static-server and static-client deployments") - k8s.DeployKustomize(t, members[keyPrimaryServer].serverOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, - "../fixtures/cases/sameness/static-server/default") - k8s.DeployKustomize(t, members[keyPartition].serverOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, - "../fixtures/cases/sameness/static-server/partition") + // Assign the client default partition client to the partition + testClusters[keyCluster01b].client = testClusters[keyCluster01a].client - // Create static client deployments. - k8s.DeployKustomize(t, members[keyPrimaryServer].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, - "../fixtures/cases/sameness/static-client/default") - k8s.DeployKustomize(t, members[keyPartition].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, - "../fixtures/cases/sameness/static-client/partition") + // Apply Mesh resource to default partition and peers + for _, v := range testClusters { + if v.hasServer { + applyResources(t, cfg, "../fixtures/bases/sameness/peering/mesh", v.context.KubectlOptions(t)) + } + } - // Verify that both static-server and static-client have been injected and now have 2 containers in server cluster. - // Also get the server IP - for _, labelSelector := range []string{"app=static-server", "app=static-client"} { - podList, err := members[keyPrimaryServer].context.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), - metav1.ListOptions{LabelSelector: labelSelector}) - require.NoError(t, err) - require.Len(t, podList.Items, 1) - require.Len(t, podList.Items[0].Spec.Containers, 2) - if labelSelector == "app=static-server" { - ip := &podList.Items[0].Status.PodIP - require.NotNil(t, ip) - logger.Logf(t, "default-static-server-ip: %s", *ip) - members[keyPrimaryServer].staticServerIP = ip + // Peering/Dialer relationship + /* + cluster-01-a cluster-02-a + Dialer -> 2a 1a -> acceptor + Dialer -> 3a 1b -> acceptor + Dialer -> 3a + + cluster-01-b cluster-03-a + Dialer -> 2a 1a -> acceptor + Dialer -> 3a 1b -> acceptor + 2a -> acceptor + */ + for _, v := range []*cluster{testClusters[keyCluster02a], testClusters[keyCluster03a]} { + logger.Logf(t, "creating acceptor on %s", v.name) + // Create an acceptor token on the cluster + applyResources(t, cfg, fmt.Sprintf("../fixtures/bases/sameness/peering/%s-acceptor", v.name), v.context.KubectlOptions(t)) + + // Copy secrets to the necessary peers to be used for dialing later + for _, vv := range testClusters { + if isAcceptor(v.name, vv.acceptors) { + acceptorSecretName := getPeeringAcceptorSecret(t, cfg, v, vv.name) + logger.Logf(t, "acceptor %s created on %s", acceptorSecretName, v.name) + + logger.Logf(t, "copying acceptor token %s from %s to %s", acceptorSecretName, v.name, vv.name) + copySecret(t, cfg, v.context, vv.context, acceptorSecretName) + } } + } - podList, err = members[keyPartition].context.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), - metav1.ListOptions{LabelSelector: labelSelector}) - require.NoError(t, err) - require.Len(t, podList.Items, 1) - require.Len(t, podList.Items[0].Spec.Containers, 2) - if labelSelector == "app=static-server" { - ip := &podList.Items[0].Status.PodIP - require.NotNil(t, ip) - logger.Logf(t, "partition-static-server-ip: %s", *ip) - members[keyPartition].staticServerIP = ip + // Create the dialers + for _, v := range []*cluster{testClusters[keyCluster01a], testClusters[keyCluster01b], testClusters[keyCluster02a]} { + applyResources(t, cfg, fmt.Sprintf("../fixtures/bases/sameness/peering/%s-dialer", v.name), v.context.KubectlOptions(t)) + } + + // If ACLs are enabled, we need to create the intentions + if c.ACLsEnabled { + intention := &api.ServiceIntentionsConfigEntry{ + Name: staticServerName, + Kind: api.ServiceIntentions, + Namespace: staticServerNamespace, + Sources: []*api.SourceIntention{ + { + Name: staticClientName, + Namespace: staticClientNamespace, + SamenessGroup: samenessGroupName, + Action: api.IntentionActionAllow, + }, + }, + } + + for _, v := range testClusters { + logger.Logf(t, "creating intentions on server %s", v.name) + _, _, err := v.client.ConfigEntries().Set(intention, &api.WriteOptions{Partition: v.partition}) + require.NoError(t, err) } } logger.Log(t, "creating exported services") - applyResources(t, cfg, "../fixtures/cases/sameness/exported-services/default-partition", members[keyPrimaryServer].context.KubectlOptions(t)) - applyResources(t, cfg, "../fixtures/cases/sameness/exported-services/ap1-partition", members[keyPartition].context.KubectlOptions(t)) + for _, v := range testClusters { + if v.hasServer { + applyResources(t, cfg, "../fixtures/cases/sameness/exported-services/default-partition", v.context.KubectlOptions(t)) + } else { + applyResources(t, cfg, "../fixtures/cases/sameness/exported-services/ap1-partition", v.context.KubectlOptions(t)) + } + } + + // Create sameness group after exporting the services, this will reduce flakiness in an automated test + for _, v := range testClusters { + applyResources(t, cfg, fmt.Sprintf("../fixtures/bases/sameness/%s-default-ns", v.name), v.context.KubectlOptions(t)) + } // Setup DNS. - dnsService, err := members[keyPrimaryServer].context.KubernetesClient(t).CoreV1().Services("default").Get(context.Background(), fmt.Sprintf("%s-%s", releaseName, "consul-dns"), metav1.GetOptions{}) - require.NoError(t, err) - dnsIP := dnsService.Spec.ClusterIP - logger.Logf(t, "dnsIP: %s", dnsIP) + for _, v := range testClusters { + dnsService, err := v.context.KubernetesClient(t).CoreV1().Services("default").Get(context.Background(), fmt.Sprintf("%s-%s", releaseName, "consul-dns"), metav1.GetOptions{}) + require.NoError(t, err) + v.dnsIP = &dnsService.Spec.ClusterIP + logger.Logf(t, "%s dnsIP: %s", v.name, *v.dnsIP) + } // Setup Prepared Query. definition := &api.PreparedQueryDefinition{ Name: "my-query", Service: api.ServiceQuery{ - Service: "static-server", - SamenessGroup: "mine", + Service: staticServerName, + SamenessGroup: samenessGroupName, Namespace: staticServerNamespace, OnlyPassing: false, }, } - resp, _, err := members[keyPrimaryServer].client.PreparedQuery().Create(definition, &api.WriteOptions{}) - require.NoError(t, err) - logger.Logf(t, "PQ ID: %s", resp) - - logger.Log(t, "all infrastructure up and running") - logger.Log(t, "verifying failover scenarios") - - const dnsLookup = "static-server.service.ns2.ns.mine.sg.consul" - const dnsPQLookup = "my-query.query.consul" - - // Verify initial server. - serviceFailoverCheck(t, primaryServerClusterName, members[keyPrimaryServer]) - // Verify initial dns. - dnsFailoverCheck(t, releaseName, dnsIP, dnsLookup, members[keyPrimaryServer], members[keyPrimaryServer]) + for k, v := range testClusters { + if v.hasServer { + pqID, _, err := v.client.PreparedQuery().Create(definition, &api.WriteOptions{}) + require.NoError(t, err) + logger.Logf(t, "%s PQ ID: %s", v.name, pqID) + testClusters[k].pqID = &pqID + testClusters[k].pqName = &definition.Name + } + } - // Verify initial dns with PQ. - dnsFailoverCheck(t, releaseName, dnsIP, dnsPQLookup, members[keyPrimaryServer], members[keyPrimaryServer]) + // Create static server/client after the rest of the config is setup for a more stable testing experience + // Create static server deployments. + logger.Log(t, "creating static-server and static-client deployments") + k8s.DeployKustomize(t, testClusters[keyCluster01a].serverOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-server/dc1-default") + k8s.DeployKustomize(t, testClusters[keyCluster01b].serverOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-server/dc1-partition") + k8s.DeployKustomize(t, testClusters[keyCluster02a].serverOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-server/dc2") + k8s.DeployKustomize(t, testClusters[keyCluster03a].serverOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-server/dc3") - // Scale down static-server on the server, will fail over to partition. - k8s.KubectlScale(t, members[keyPrimaryServer].serverOpts, staticServerDeployment, 0) + // Create static client deployments. + k8s.DeployKustomize(t, testClusters[keyCluster01a].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-client/default-partition") + k8s.DeployKustomize(t, testClusters[keyCluster02a].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-client/default-partition") + k8s.DeployKustomize(t, testClusters[keyCluster03a].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-client/default-partition") + k8s.DeployKustomize(t, testClusters[keyCluster01b].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, + "../fixtures/cases/sameness/static-client/ap1-partition") + + // Verify that both static-server and static-client have been injected and now have 2 containers in each cluster. + // Also get the server IP + testClusters.setServerIP(t) - // Verify failover to partition. - serviceFailoverCheck(t, partitionClusterName, members[keyPrimaryServer]) + // Everything should be up and running now + testClusters.verifyServerUpState(t) + logger.Log(t, "all infrastructure up and running") - // Verify dns failover to partition. - dnsFailoverCheck(t, releaseName, dnsIP, dnsLookup, members[keyPrimaryServer], members[keyPartition]) + // Verify all the failover Scenarios + logger.Log(t, "verifying failover scenarios") - // Verify prepared query failover. - dnsFailoverCheck(t, releaseName, dnsIP, dnsPQLookup, members[keyPrimaryServer], members[keyPartition]) + subCases := []struct { + name string + server *cluster + failovers []struct { + failoverServer *cluster + expectedPQ expectedPQ + } + checkDNSPQ bool + }{ + { + name: "cluster-01-a perspective", // This matches the diagram at the beginning of the test + server: testClusters[keyCluster01a], + failovers: []struct { + failoverServer *cluster + expectedPQ expectedPQ + }{ + {failoverServer: testClusters[keyCluster01a], expectedPQ: expectedPQ{partition: "default", peerName: "", namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster01b], expectedPQ: expectedPQ{partition: "ap1", peerName: "", namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster02a], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster02a].name, namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster03a], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster03a].name, namespace: "ns2"}}, + }, + checkDNSPQ: true, + }, + { + name: "cluster-01-b partition perspective", + server: testClusters[keyCluster01b], + failovers: []struct { + failoverServer *cluster + expectedPQ expectedPQ + }{ + {failoverServer: testClusters[keyCluster01b], expectedPQ: expectedPQ{partition: "ap1", peerName: "", namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster01a], expectedPQ: expectedPQ{partition: "default", peerName: "", namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster02a], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster02a].name, namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster03a], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster03a].name, namespace: "ns2"}}, + }, + checkDNSPQ: false, + }, + { + name: "cluster-02-a perspective", + server: testClusters[keyCluster02a], + failovers: []struct { + failoverServer *cluster + expectedPQ expectedPQ + }{ + {failoverServer: testClusters[keyCluster02a], expectedPQ: expectedPQ{partition: "default", peerName: "", namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster01a], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster01a].name, namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster01b], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster01b].name, namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster03a], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster03a].name, namespace: "ns2"}}, + }, + checkDNSPQ: true, + }, + { + name: "cluster-03-a perspective", + server: testClusters[keyCluster03a], + failovers: []struct { + failoverServer *cluster + expectedPQ expectedPQ + }{ + {failoverServer: testClusters[keyCluster03a], expectedPQ: expectedPQ{partition: "default", peerName: "", namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster01a], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster01a].name, namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster01b], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster01b].name, namespace: "ns2"}}, + {failoverServer: testClusters[keyCluster02a], expectedPQ: expectedPQ{partition: "default", peerName: testClusters[keyCluster02a].name, namespace: "ns2"}}, + }, + checkDNSPQ: true, + }, + } - logger.Log(t, "tests complete") + for _, sc := range subCases { + t.Run(sc.name, func(t *testing.T) { + // Reset the scale of all servers + testClusters.resetScale(t) + testClusters.verifyServerUpState(t) + // We're resetting the scale, so make sure we have all the new IP addresses saved + testClusters.setServerIP(t) + + for _, v := range sc.failovers { + // Verify Failover (If this is the first check, then just verifying we're starting with the right server) + logger.Log(t, "checking service failover") + serviceFailoverCheck(t, sc.server, v.failoverServer.name) + + // Verify DNS + if sc.checkDNSPQ { + logger.Log(t, "verifying dns") + dnsFailoverCheck(t, cfg, releaseName, *sc.server.dnsIP, sc.server, v.failoverServer) + + // Verify PQ + logger.Log(t, "verifying prepared query") + preparedQueryFailoverCheck(t, releaseName, *sc.server.dnsIP, v.expectedPQ, sc.server, v.failoverServer) + } else { + // We currently skip running DNS and PQ tests for a couple of reasons + // 1. The admin partition does not contain a server, so DNS service will not resolve on the admin partition cluster + // 2. A workaround to perform the DNS and PQ queries on the primary datacenter cluster by specifying the admin partition + // e.g kubectl --context kind-dc1 --namespace ns1 exec -i deploy/static-client -c static-client \ + // -- dig @test-3lmypr-consul-dns.default static-server.service.ns2.ns.mine.sg.ap1.ap.consul + // is not possible at the moment due to a bug. The workaround will be used once this bug is fixed. + logger.Logf(t, "skipping DNS and PQ checks for %s", sc.name) + } + + // Scale down static-server on the current failover, will fail over to the next. + logger.Logf(t, "scaling server down on %s", v.failoverServer.name) + k8s.KubectlScale(t, v.failoverServer.serverOpts, staticServerDeployment, 0) + } + }) + } }) } } -type member struct { +type expectedPQ struct { + partition string + peerName string + namespace string +} + +type cluster struct { + name string + partition string context environment.TestContext helmCluster *consul.HelmCluster client *api.Client @@ -400,6 +572,56 @@ type member struct { serverOpts *terratestk8s.KubectlOptions clientOpts *terratestk8s.KubectlOptions staticServerIP *string + pqID *string + pqName *string + dnsIP *string + acceptors []string +} + +type clusters map[string]*cluster + +func (c clusters) resetScale(t *testing.T) { + for _, v := range c { + k8s.KubectlScale(t, v.serverOpts, staticServerDeployment, 1) + } +} + +// setServerIP makes sure everything is up and running and then saves the +// static-server IP to the appropriate cluster. IP addresses can change when +// services are scaled up and down. +func (c clusters) setServerIP(t *testing.T) { + for _, labelSelector := range []string{"app=static-server", "app=static-client"} { + for k, v := range c { + podList, err := v.context.KubernetesClient(t).CoreV1().Pods(metav1.NamespaceAll).List(context.Background(), + metav1.ListOptions{LabelSelector: labelSelector}) + require.NoError(t, err) + require.Len(t, podList.Items, 1) + require.Len(t, podList.Items[0].Spec.Containers, 2) + if labelSelector == "app=static-server" { + ip := &podList.Items[0].Status.PodIP + require.NotNil(t, ip) + logger.Logf(t, "%s-static-server-ip: %s", v.name, *ip) + c[k].staticServerIP = ip + } + } + } +} + +// verifyServerUpState will verify that the static-servers are all up and running as +// expected by curling them from their local datacenters. +func (c clusters) verifyServerUpState(t *testing.T) { + logger.Logf(t, "verifying that static-servers are up") + for _, v := range c { + // Query using a client and expect its own name, no failover should occur + serviceFailoverCheck(t, v, v.name) + } +} + +func copySecret(t *testing.T, cfg *config.TestConfig, sourceContext, destContext environment.TestContext, secretName string) { + k8s.CopySecret(t, sourceContext, destContext, secretName) + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + k8s.RunKubectl(t, destContext.KubectlOptions(t), "delete", "secret", secretName) + }) } func createNamespaces(t *testing.T, cfg *config.TestConfig, context environment.TestContext) { @@ -421,37 +643,111 @@ func applyResources(t *testing.T, cfg *config.TestConfig, kustomizeDir string, o // serviceFailoverCheck verifies that the server failed over as expected by checking that curling the `static-server` // using the `static-client` responds with the expected cluster name. Each static-server responds with a uniquue // name so that we can verify failover occured as expected. -func serviceFailoverCheck(t *testing.T, expectedClusterName string, server *member) { - retry.Run(t, func(r *retry.R) { - resp, err := k8s.RunKubectlAndGetOutputE(t, server.clientOpts, "exec", "-i", - staticClientDeployment, "-c", "static-client", "--", "curl", "localhost:8080") +func serviceFailoverCheck(t *testing.T, server *cluster, expectedName string) { + timer := &retry.Timer{Timeout: retryTimeout, Wait: 5 * time.Second} + var resp string + var err error + retry.RunWith(timer, t, func(r *retry.R) { + resp, err = k8s.RunKubectlAndGetOutputE(t, server.clientOpts, "exec", "-i", + staticClientDeployment, "-c", staticClientName, "--", "curl", "localhost:8080") require.NoError(r, err) - assert.Contains(r, resp, expectedClusterName) - logger.Log(t, resp) + assert.Contains(r, resp, expectedName) }) + logger.Log(t, resp) } -func dnsFailoverCheck(t *testing.T, releaseName string, dnsIP string, dnsQuery string, server, failover *member) { - retry.Run(t, func(r *retry.R) { - logs, err := k8s.RunKubectlAndGetOutputE(t, server.clientOpts, "exec", "-i", - staticClientDeployment, "-c", "static-client", "--", "dig", fmt.Sprintf("@%s-consul-dns.default", releaseName), dnsQuery) - require.NoError(r, err) +// preparedQueryFailoverCheck verifies that failover occurs when executing the prepared query. It also assures that +// executing the prepared query via DNS also provides expected results. +func preparedQueryFailoverCheck(t *testing.T, releaseName string, dnsIP string, epq expectedPQ, server, failover *cluster) { + timer := &retry.Timer{Timeout: retryTimeout, Wait: 5 * time.Second} + resp, _, err := server.client.PreparedQuery().Execute(*server.pqID, &api.QueryOptions{Namespace: staticServerNamespace, Partition: server.partition}) + require.NoError(t, err) + require.Len(t, resp.Nodes, 1) + + assert.Equal(t, epq.partition, resp.Nodes[0].Service.Partition) + assert.Equal(t, epq.peerName, resp.Nodes[0].Service.PeerName) + assert.Equal(t, epq.namespace, resp.Nodes[0].Service.Namespace) + assert.Equal(t, *failover.staticServerIP, resp.Nodes[0].Service.Address) + + // Verify that dns lookup is successful, there is no guarantee that the ip address is unique, so for PQ this is + // just verifying that we can query using DNS and that the ip address is correct. It does not however prove + // that failover occured, that is left to client `Execute` + dnsPQLookup := []string{fmt.Sprintf("%s.query.consul", *server.pqName)} + retry.RunWith(timer, t, func(r *retry.R) { + logs := dnsQuery(t, releaseName, dnsPQLookup, server, failover) + assert.Contains(r, logs, fmt.Sprintf("SERVER: %s", dnsIP)) + assert.Contains(r, logs, "ANSWER SECTION:") + assert.Contains(r, logs, *failover.staticServerIP) + }) +} - // When the `dig` request is successful, a section of its response looks like the following: - // - // ;; ANSWER SECTION: - // static-server.service.mine.sg.ns2.ns.consul. 0 IN A - // - // ;; Query time: 2 msec - // ;; SERVER: #() - // ;; WHEN: Mon Aug 10 15:02:40 UTC 2020 - // ;; MSG SIZE rcvd: 98 - // - // We assert on the existence of the ANSWER SECTION, The consul-server IPs being present in - // the ANSWER SECTION and the DNS IP mentioned in the SERVER: field +// DNS failover check verifies that failover occurred when querying the DNS. +func dnsFailoverCheck(t *testing.T, cfg *config.TestConfig, releaseName string, dnsIP string, server, failover *cluster) { + timer := &retry.Timer{Timeout: retryTimeout, Wait: 5 * time.Second} + dnsLookup := []string{fmt.Sprintf("static-server.service.ns2.ns.%s.sg.consul", samenessGroupName), "+tcp", "SRV"} + retry.RunWith(timer, t, func(r *retry.R) { + logs := dnsQuery(t, releaseName, dnsLookup, server, failover) assert.Contains(r, logs, fmt.Sprintf("SERVER: %s", dnsIP)) assert.Contains(r, logs, "ANSWER SECTION:") assert.Contains(r, logs, *failover.staticServerIP) + + // Additional checks + // When accessing the SRV record for DNS we can get more information. In the case of Kind, + // the context can be used to determine that failover occured to the expected kubernetes cluster + // hosting Consul + assert.Contains(r, logs, "ADDITIONAL SECTION:") + expectedName := failover.context.KubectlOptions(t).ContextName + if cfg.UseKind { + expectedName = strings.Replace(expectedName, "kind-", "", -1) + } + assert.Contains(r, logs, expectedName) + }) +} + +// dnsQuery performs a dns query with the provided query string. +func dnsQuery(t *testing.T, releaseName string, dnsQuery []string, server, failover *cluster) string { + timer := &retry.Timer{Timeout: retryTimeout, Wait: 1 * time.Second} + var logs string + retry.RunWith(timer, t, func(r *retry.R) { + args := []string{"exec", "-i", + staticClientDeployment, "-c", staticClientName, "--", "dig", fmt.Sprintf("@%s-consul-dns.default", + releaseName)} + args = append(args, dnsQuery...) + var err error + logs, err = k8s.RunKubectlAndGetOutputE(t, server.clientOpts, args...) + require.NoError(r, err) }) + logger.Logf(t, "%s: %s", failover.name, logs) + return logs +} + +// isAcceptor iterates through the provided acceptor list of cluster names and determines if +// any match the provided name. Returns true if a match is found, false otherwise. +func isAcceptor(name string, acceptorList []string) bool { + for _, v := range acceptorList { + if name == v { + return true + } + } + return false +} + +// getPeeringAcceptorSecret assures that the secret is created and retrieves the secret from the provided acceptor. +func getPeeringAcceptorSecret(t *testing.T, cfg *config.TestConfig, server *cluster, acceptorName string) string { + // Ensure the secrets are created. + var acceptorSecretName string + timer := &retry.Timer{Timeout: retryTimeout, Wait: 1 * time.Second} + retry.RunWith(timer, t, func(r *retry.R) { + var err error + acceptorSecretName, err = k8s.RunKubectlAndGetOutputE(t, server.context.KubectlOptions(t), "get", "peeringacceptor", acceptorName, "-o", "jsonpath={.status.secret.name}") + require.NoError(r, err) + require.NotEmpty(r, acceptorSecretName) + }) + + helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { + k8s.RunKubectl(t, server.context.KubectlOptions(t), "delete", "secret", acceptorSecretName) + }) + + return acceptorSecretName } From 6e9f4731e76642dbb5d0869cdf1aa3fa40e1681a Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Mon, 14 Aug 2023 11:12:59 -0400 Subject: [PATCH 115/120] Updates changelog to include 1.0.9 (#2758) --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa47db462e..52529c952a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,36 @@ +## 1.0.9 (Aug 10, 2023) + +SECURITY: + +* Upgrade to use Go 1.19.11 and `x/net/http` 0.12.0. + This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2650](https://github.com/hashicorp/consul-k8s/issues/2650)] +* Upgrade to use Go 1.19.12 and `x/net` 0.13.0. + This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) + and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2717](https://github.com/hashicorp/consul-k8s/issues/2717)] + +IMPROVEMENTS: + +* Add support to provide the logLevel flag via helm for multiple low level components. Introduces the following fields +1. `global.acls.logLevel` +2. `global.tls.logLevel` +3. `global.federation.logLevel` +4. `global.gossipEncryption.logLevel` +5. `server.logLevel` +6. `client.logLevel` +7. `meshGateway.logLevel` +8. `ingressGateways.logLevel` +9. `terminatingGateways.logLevel` [[GH-2302](https://github.com/hashicorp/consul-k8s/issues/2302)] +* control-plane: increase timeout after login for ACL replication to 60 seconds [[GH-2656](https://github.com/hashicorp/consul-k8s/issues/2656)] +* helm: adds values for `securityContext` and `annotations` on TLS and ACL init/cleanup jobs. [[GH-2525](https://github.com/hashicorp/consul-k8s/issues/2525)] +* helm: do not set container securityContexts by default on OpenShift < 4.11 [[GH-2678](https://github.com/hashicorp/consul-k8s/issues/2678)] +* helm: set container securityContexts to match the `restricted` Pod Security Standards policy to support running Consul in a namespace with restricted PSA enforcement enabled [[GH-2572](https://github.com/hashicorp/consul-k8s/issues/2572)] + +BUG FIXES: + +* control-plane: fix bug in endpoints controller when deregistering services from consul when a node is deleted. [[GH-2571](https://github.com/hashicorp/consul-k8s/issues/2571)] +* helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. [[GH-2652](https://github.com/hashicorp/consul-k8s/issues/2652)] +* helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. [[GH-2687](https://github.com/hashicorp/consul-k8s/issues/2687)] + ## 1.1.4 (Aug 10, 2023) SECURITY: From ab00c033f386f5f3fdc1614092c1494ca36e6a1b Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Tue, 15 Aug 2023 09:37:16 -0400 Subject: [PATCH 116/120] Adds changelog for 1.2.1, reorders 1.1.4 and 1.0.9 (#2768) --- CHANGELOG.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52529c952a..d9a4d76bef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,28 @@ -## 1.0.9 (Aug 10, 2023) +## 1.2.1 (Aug 10, 2023) +BREAKING CHANGES: + +* control-plane: All policies managed by consul-k8s will now be updated on upgrade. If you previously edited the policies after install, your changes will be overwritten. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] SECURITY: -* Upgrade to use Go 1.19.11 and `x/net/http` 0.12.0. - This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2650](https://github.com/hashicorp/consul-k8s/issues/2650)] -* Upgrade to use Go 1.19.12 and `x/net` 0.13.0. +* Upgrade to use Go 1.20.6 and `x/net/http` 0.12.0. + This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2642](https://github.com/hashicorp/consul-k8s/issues/2642)] +* Upgrade to use Go 1.20.7 and `x/net` 0.13.0. This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) - and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2717](https://github.com/hashicorp/consul-k8s/issues/2717)] + and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2710](https://github.com/hashicorp/consul-k8s/issues/2710)] + +FEATURES: + +* Add support for configuring graceful shutdown proxy lifecycle management settings. [[GH-2233](https://github.com/hashicorp/consul-k8s/issues/2233)] +* api-gateway: adds ability to map privileged ports on Gateway listeners to unprivileged ports so that containers do not require additional privileges [[GH-2707](https://github.com/hashicorp/consul-k8s/issues/2707)] +* api-gateway: support deploying to OpenShift 4.11 [[GH-2184](https://github.com/hashicorp/consul-k8s/issues/2184)] +* helm: Adds `acls.resources` field which can be configured to override the `resource` settings for the `server-acl-init` and `server-acl-init-cleanup` Jobs. [[GH-2416](https://github.com/hashicorp/consul-k8s/issues/2416)] +* sync-catalog: add ability to support weighted loadbalancing by service annotation `consul.hashicorp.com/service-weight: ` [[GH-2293](https://github.com/hashicorp/consul-k8s/issues/2293)] IMPROVEMENTS: +* (Consul Enterprise) Add support to provide inputs via helm for audit log related configuration [[GH-2370](https://github.com/hashicorp/consul-k8s/issues/2370)] +* (api-gateway) make API gateway controller less verbose [[GH-2524](https://github.com/hashicorp/consul-k8s/issues/2524)] * Add support to provide the logLevel flag via helm for multiple low level components. Introduces the following fields 1. `global.acls.logLevel` 2. `global.tls.logLevel` @@ -19,17 +32,28 @@ IMPROVEMENTS: 6. `client.logLevel` 7. `meshGateway.logLevel` 8. `ingressGateways.logLevel` -9. `terminatingGateways.logLevel` [[GH-2302](https://github.com/hashicorp/consul-k8s/issues/2302)] +9. `terminatingGateways.logLevel` +10. `telemetryCollector.logLevel` [[GH-2302](https://github.com/hashicorp/consul-k8s/issues/2302)] * control-plane: increase timeout after login for ACL replication to 60 seconds [[GH-2656](https://github.com/hashicorp/consul-k8s/issues/2656)] * helm: adds values for `securityContext` and `annotations` on TLS and ACL init/cleanup jobs. [[GH-2525](https://github.com/hashicorp/consul-k8s/issues/2525)] -* helm: do not set container securityContexts by default on OpenShift < 4.11 [[GH-2678](https://github.com/hashicorp/consul-k8s/issues/2678)] * helm: set container securityContexts to match the `restricted` Pod Security Standards policy to support running Consul in a namespace with restricted PSA enforcement enabled [[GH-2572](https://github.com/hashicorp/consul-k8s/issues/2572)] +* helm: update `imageConsulDataplane` value to `hashicorp/consul-dataplane:1.2.0` [[GH-2476](https://github.com/hashicorp/consul-k8s/issues/2476)] +* helm: update `image` value to `hashicorp/consul:1.16.0` [[GH-2476](https://github.com/hashicorp/consul-k8s/issues/2476)] BUG FIXES: +* api-gateway: Fix creation of invalid Kubernetes Service when multiple Gateway listeners have the same port. [[GH-2413](https://github.com/hashicorp/consul-k8s/issues/2413)] +* api-gateway: fix helm install when setting copyAnnotations or nodeSelector [[GH-2597](https://github.com/hashicorp/consul-k8s/issues/2597)] +* api-gateway: fixes bug where envoy will silently reject RSA keys less than 2048 bits in length when not in FIPS mode, and + will reject keys that are not 2048, 3072, or 4096 bits in length in FIPS mode. We now validate + and reject invalid certs earlier. [[GH-2478](https://github.com/hashicorp/consul-k8s/issues/2478)] +* api-gateway: set route condition appropriately when parent ref includes non-existent section name [[GH-2420](https://github.com/hashicorp/consul-k8s/issues/2420)] +* control-plane: Always update ACL policies upon upgrade. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] * control-plane: fix bug in endpoints controller when deregistering services from consul when a node is deleted. [[GH-2571](https://github.com/hashicorp/consul-k8s/issues/2571)] * helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. [[GH-2652](https://github.com/hashicorp/consul-k8s/issues/2652)] * helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. [[GH-2687](https://github.com/hashicorp/consul-k8s/issues/2687)] +* transparent-proxy: Fix issue where connect-inject lacked sufficient `mesh:write` privileges in some deployments, + which prevented virtual IPs from persisting properly. [[GH-2520](https://github.com/hashicorp/consul-k8s/issues/2520)] ## 1.1.4 (Aug 10, 2023) @@ -65,6 +89,39 @@ BUG FIXES: * helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. [[GH-2652](https://github.com/hashicorp/consul-k8s/issues/2652)] * helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. [[GH-2687](https://github.com/hashicorp/consul-k8s/issues/2687)] +## 1.0.9 (Aug 10, 2023) + +SECURITY: + +* Upgrade to use Go 1.19.11 and `x/net/http` 0.12.0. + This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2650](https://github.com/hashicorp/consul-k8s/issues/2650)] +* Upgrade to use Go 1.19.12 and `x/net` 0.13.0. + This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) + and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2717](https://github.com/hashicorp/consul-k8s/issues/2717)] + +IMPROVEMENTS: + +* Add support to provide the logLevel flag via helm for multiple low level components. Introduces the following fields +1. `global.acls.logLevel` +2. `global.tls.logLevel` +3. `global.federation.logLevel` +4. `global.gossipEncryption.logLevel` +5. `server.logLevel` +6. `client.logLevel` +7. `meshGateway.logLevel` +8. `ingressGateways.logLevel` +9. `terminatingGateways.logLevel` [[GH-2302](https://github.com/hashicorp/consul-k8s/issues/2302)] +* control-plane: increase timeout after login for ACL replication to 60 seconds [[GH-2656](https://github.com/hashicorp/consul-k8s/issues/2656)] +* helm: adds values for `securityContext` and `annotations` on TLS and ACL init/cleanup jobs. [[GH-2525](https://github.com/hashicorp/consul-k8s/issues/2525)] +* helm: do not set container securityContexts by default on OpenShift < 4.11 [[GH-2678](https://github.com/hashicorp/consul-k8s/issues/2678)] +* helm: set container securityContexts to match the `restricted` Pod Security Standards policy to support running Consul in a namespace with restricted PSA enforcement enabled [[GH-2572](https://github.com/hashicorp/consul-k8s/issues/2572)] + +BUG FIXES: + +* control-plane: fix bug in endpoints controller when deregistering services from consul when a node is deleted. [[GH-2571](https://github.com/hashicorp/consul-k8s/issues/2571)] +* helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. [[GH-2652](https://github.com/hashicorp/consul-k8s/issues/2652)] +* helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. [[GH-2687](https://github.com/hashicorp/consul-k8s/issues/2687)] + ## 0.49.8 (July 12, 2023) IMPROVEMENTS: From c188b538d26e73f17fa8cddf21d5df4e37f15f13 Mon Sep 17 00:00:00 2001 From: Jitendra Gangwar Date: Wed, 16 Aug 2023 19:20:43 +0530 Subject: [PATCH 117/120] correct prometheus port and scheme annotations if tls is enabled --- charts/consul/templates/server-statefulset.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 2ad04f0755..74613b19ff 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -119,7 +119,13 @@ spec: {{- if (and .Values.global.metrics.enabled .Values.global.metrics.enableAgentMetrics) }} "prometheus.io/scrape": "true" "prometheus.io/path": "/v1/agent/metrics" + {{- if .Values.global.tls.enabled }} + "prometheus.io/port": "8501" + "prometheus.io/scheme": "https" + {{- else }} "prometheus.io/port": "8500" + "prometheus.io/scheme": "http" + {{- end }} {{- end }} spec: {{- if .Values.server.affinity }} From 1318f3af0bb4b275ddb1f8744acf3310b052e013 Mon Sep 17 00:00:00 2001 From: Jitendra Gangwar Date: Wed, 16 Aug 2023 19:27:48 +0530 Subject: [PATCH 118/120] added changelog file --- .changelog/2782.txt | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/2782.txt diff --git a/.changelog/2782.txt b/.changelog/2782.txt new file mode 100644 index 0000000000..f01db6bafa --- /dev/null +++ b/.changelog/2782.txt @@ -0,0 +1,3 @@ +```release-note:bug +helm: Update prometheus port and scheme annotations if tls is enabled +``` From bdbc01e29957508d29efa94426dba6e7728ae87f Mon Sep 17 00:00:00 2001 From: Jitendra Gangwar Date: Wed, 16 Aug 2023 13:57:48 +0000 Subject: [PATCH 119/120] backport of commit 1318f3af0bb4b275ddb1f8744acf3310b052e013 --- .changelog/2194.txt | 2 +- .changelog/2346.txt | 3 - .changelog/2357.txt | 3 - .changelog/{2265.txt => 2370.txt} | 2 +- .changelog/2748.txt | 3 - .changelog/2787.txt | 3 + .changelog/2789.txt | 3 + .changelog/2808.txt | 3 + .github/pull_request_template.md | 5 +- .github/workflows/backport.yml | 2 +- .github/workflows/build.yml | 20 +- .github/workflows/changelog-checker.yml | 2 +- .github/workflows/jira-issues.yaml | 6 +- .github/workflows/jira-pr.yaml | 6 +- .../nightly-api-gateway-conformance.yml | 27 -- CHANGELOG.md | 168 +---------- Makefile | 2 +- .../framework/connhelper/connect_helper.go | 110 +++++++- acceptance/framework/flags/flags.go | 12 +- acceptance/framework/k8s/deploy.go | 34 ++- acceptance/framework/vault/vault_cluster.go | 23 -- acceptance/go.mod | 22 +- acceptance/go.sum | 131 +-------- .../api_gateway_gatewayclassconfig_test.go | 3 +- .../tests/api-gateway/api_gateway_test.go | 253 +---------------- acceptance/tests/cloud/basic_test.go | 61 +--- acceptance/tests/cloud/remote_dev_test.go | 264 ------------------ .../tests/connect/connect_inject_test.go | 12 + .../connect/connect_proxy_lifecycle_test.go | 171 +++++++++++- .../tests/connect/permissive_mtls_test.go | 2 +- .../bases/cloud/service-intentions/acl.yaml | 15 - .../tests/fixtures/bases/job-client/job.yaml | 27 ++ .../kustomization.yaml | 4 +- .../fixtures/bases/job-client/service.yaml | 10 + .../bases/job-client/serviceaccount.yaml | 5 + .../override-ns/service-defaults.yaml | 3 - .../bases/sameness/peering/mesh/mesh.yaml | 3 - .../api-gateways/jwt-auth/api-gateway.yaml | 37 --- .../api-gateways/jwt-auth/gateway-policy.yaml | 24 -- .../api-gateways/jwt-auth/httproute-auth.yaml | 32 --- .../api-gateways/jwt-auth/httproute.yaml | 19 -- .../api-gateways/jwt-auth/jwt-provider.yaml | 9 - .../jwt-auth/jwt-route-filter.yaml | 12 - .../api-gateways/jwt-auth/kustomization.yaml | 12 - .../kustomization.yaml | 6 + .../patch.yaml | 12 + .../kustomization.yaml | 6 + .../patch.yaml | 12 + .../jobs/job-client-inject/kustomization.yaml | 8 + .../cases/jobs/job-client-inject/patch.yaml | 12 + .../ap1-partition-tproxy/kustomization.yaml | 8 + .../ap1-partition-tproxy/patch.yaml | 21 ++ .../kustomization.yaml | 8 + .../default-partition-tproxy/patch.yaml | 21 ++ acceptance/tests/sameness/sameness_test.go | 52 +++- acceptance/tests/vault/vault_wan_fed_test.go | 3 - charts/consul/Chart.yaml | 12 +- charts/consul/templates/_helpers.tpl | 3 + .../consul/templates/crd-gatewayclasses.yaml | 1 - charts/consul/templates/crd-gateways.yaml | 1 - charts/consul/templates/crd-grpcroutes.yaml | 1 - charts/consul/templates/crd-httproutes.yaml | 1 - .../consul/templates/crd-referencegrants.yaml | 6 +- .../templates/crd-serviceresolvers.yaml | 10 - .../ingress-gateways-deployment.yaml | 7 + .../consul/templates/server-statefulset.yaml | 6 +- .../telemetry-collector-deployment.yaml | 2 +- .../terminating-gateways-deployment.yaml | 7 + charts/consul/test/terraform/aks/main.tf | 2 +- charts/consul/test/terraform/aks/variables.tf | 5 + charts/consul/test/terraform/eks/main.tf | 13 +- .../test/unit/connect-inject-deployment.bats | 1 + .../test/unit/server-config-configmap.bats | 2 +- .../consul/test/unit/server-statefulset.bats | 8 +- charts/consul/todo.txt | 3 + charts/consul/values.yaml | 124 ++++---- cli/version/version.go | 2 +- .../gateway_controller_integration_test.go | 2 - .../api/v1alpha1/serviceresolver_types.go | 61 +--- .../v1alpha1/serviceresolver_types_test.go | 28 -- .../api/v1alpha1/zz_generated.deepcopy.go | 20 -- .../build-support/functions/10-util.sh | 6 +- .../build-support/functions/20-build.sh | 2 +- .../build-support/scripts/consul-version.sh | 1 + control-plane/catalog/to-consul/resource.go | 6 +- ...consul.hashicorp.com_serviceresolvers.yaml | 10 - .../endpoints/endpoints_controller.go | 22 -- .../endpoints/endpoints_controller_test.go | 53 +--- .../peering_acceptor_controller_test.go | 19 +- .../peering/peering_dialer_controller_test.go | 34 ++- .../webhook/consul_dataplane_sidecar.go | 25 +- .../webhook/consul_dataplane_sidecar_test.go | 20 +- control-plane/version/version.go | 2 +- hack/aws-acceptance-test-cleanup/main.go | 125 --------- 94 files changed, 779 insertions(+), 1613 deletions(-) delete mode 100644 .changelog/2346.txt delete mode 100644 .changelog/2357.txt rename .changelog/{2265.txt => 2370.txt} (96%) delete mode 100644 .changelog/2748.txt create mode 100644 .changelog/2787.txt create mode 100644 .changelog/2789.txt create mode 100644 .changelog/2808.txt delete mode 100644 .github/workflows/nightly-api-gateway-conformance.yml delete mode 100644 acceptance/tests/cloud/remote_dev_test.go delete mode 100644 acceptance/tests/fixtures/bases/cloud/service-intentions/acl.yaml create mode 100644 acceptance/tests/fixtures/bases/job-client/job.yaml rename acceptance/tests/fixtures/bases/{cloud/service-intentions => job-client}/kustomization.yaml (58%) create mode 100644 acceptance/tests/fixtures/bases/job-client/service.yaml create mode 100644 acceptance/tests/fixtures/bases/job-client/serviceaccount.yaml delete mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/api-gateway.yaml delete mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/gateway-policy.yaml delete mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute-auth.yaml delete mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute.yaml delete mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-provider.yaml delete mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-route-filter.yaml delete mode 100644 acceptance/tests/fixtures/cases/api-gateways/jwt-auth/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-0s/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-0s/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-10s/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-10s/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/jobs/job-client-inject/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/jobs/job-client-inject/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition-tproxy/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition-tproxy/patch.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-client/default-partition-tproxy/kustomization.yaml create mode 100644 acceptance/tests/fixtures/cases/sameness/static-client/default-partition-tproxy/patch.yaml create mode 100644 charts/consul/todo.txt diff --git a/.changelog/2194.txt b/.changelog/2194.txt index fb265d9739..997326218b 100644 --- a/.changelog/2194.txt +++ b/.changelog/2194.txt @@ -1,3 +1,3 @@ -```release-note:bug +```release-note: crd: fix bug on service intentions CRD causing some updates to be ignored. ``` diff --git a/.changelog/2346.txt b/.changelog/2346.txt deleted file mode 100644 index fb062ee0fb..0000000000 --- a/.changelog/2346.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -Set locality on services registered with connect-inject. -``` diff --git a/.changelog/2357.txt b/.changelog/2357.txt deleted file mode 100644 index 7cc35f595a..0000000000 --- a/.changelog/2357.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:feature -Add the `PrioritizeByLocality` field to the `ServiceResolver` CRD. -``` diff --git a/.changelog/2265.txt b/.changelog/2370.txt similarity index 96% rename from .changelog/2265.txt rename to .changelog/2370.txt index 1cf6813c94..35643ce272 100644 --- a/.changelog/2265.txt +++ b/.changelog/2370.txt @@ -1,3 +1,3 @@ ```release-note:improvement (Consul Enterprise) Add support to provide inputs via helm for audit log related configuration -``` +``` \ No newline at end of file diff --git a/.changelog/2748.txt b/.changelog/2748.txt deleted file mode 100644 index 2a8c922d13..0000000000 --- a/.changelog/2748.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -control-plane: Set locality on sidecar proxies in addition to services when registering with connect-inject. -``` diff --git a/.changelog/2787.txt b/.changelog/2787.txt new file mode 100644 index 0000000000..2fe921ef23 --- /dev/null +++ b/.changelog/2787.txt @@ -0,0 +1,3 @@ +```release-note:improvement +Add NET_BIND_SERVICE capability to restricted security context used for consul-dataplane +``` diff --git a/.changelog/2789.txt b/.changelog/2789.txt new file mode 100644 index 0000000000..c8db7d0f08 --- /dev/null +++ b/.changelog/2789.txt @@ -0,0 +1,3 @@ +```release-note:improvement +helm: Add readOnlyRootFilesystem to the default restricted security context when runnning `consul-k8s` in a restricted namespaces. +``` diff --git a/.changelog/2808.txt b/.changelog/2808.txt new file mode 100644 index 0000000000..d6d0270e44 --- /dev/null +++ b/.changelog/2808.txt @@ -0,0 +1,3 @@ +```release-note:bug +control-plane: Fix issue where ACL tokens would have an empty pod name that prevented proper token cleanup. +``` diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f5d211b137..b615e69dd1 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,6 +9,7 @@ How I expect reviewers to test this PR: Checklist: - [ ] Tests added -- [ ] [CHANGELOG entry added](https://github.com/hashicorp/consul-k8s/blob/main/CONTRIBUTING.md#adding-a-changelog-entry) - +- [ ] CHANGELOG entry added + > HashiCorp engineers only, community PRs should not add a changelog entry. + > Entries should use present tense (e.g. Add support for...) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index dadde6a651..7f39b4e5a0 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -13,7 +13,7 @@ jobs: backport: if: github.event.pull_request.merged runs-on: ubuntu-latest - container: hashicorpdev/backport-assistant:0.3.4 + container: hashicorpdev/backport-assistant:0.3.3 steps: - name: Run Backport Assistant run: backport-assistant backport -merge-method=squash -gh-automerge diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 414c875b26..e08a6a851b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: outputs: go-version: ${{ steps.get-go-version.outputs.go-version }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Determine Go version id: get-go-version # We use .go-version as our source of truth for current Go @@ -35,7 +35,7 @@ jobs: outputs: product-version: ${{ steps.get-product-version.outputs.product-version }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: get product version id: get-product-version run: | @@ -49,7 +49,7 @@ jobs: filepath: ${{ steps.generate-metadata-file.outputs.filepath }} steps: - name: "Checkout directory" - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Generate metadata file id: generate-metadata-file uses: hashicorp/actions-generate-metadata@v1 @@ -121,10 +121,10 @@ jobs: name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} ${{ matrix.component }} ${{ matrix.fips }} build steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - name: Setup go - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 + uses: actions/setup-go@4d34df0c2316fe8122ab82dc22947d607c0c91f9 # v4.0.0 with: go-version: ${{ matrix.go }} @@ -193,7 +193,7 @@ jobs: - name: Test rpm package if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} - uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 # v3 + uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" with: image: registry.access.redhat.com/ubi9/ubi:latest options: -v ${{ github.workspace }}:/work @@ -218,7 +218,7 @@ jobs: - name: Test debian package if: ${{ matrix.goos == 'linux' && matrix.component == 'cli' && matrix.goarch == 'amd64'}} - uses: addnab/docker-run-action@4f65fabd2431ebc8d299f8e5a018d79a769ae185 # v3 + uses: addnab/docker-run-action@v3 # TSCCR: no entry for repository "addnab/docker-run-action" with: image: ubuntu:latest options: -v ${{ github.workspace }}:/work @@ -258,7 +258,7 @@ jobs: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_${{ matrix.goos}}_${{ matrix.goarch }}.zip @@ -328,7 +328,7 @@ jobs: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_linux_${{ matrix.arch }}.zip @@ -391,7 +391,7 @@ jobs: repo: ${{ github.event.repository.name }} version: ${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }} steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 with: name: consul-cni_${{ needs.get-product-version.outputs.product-version }}${{ matrix.fips }}_linux_${{ matrix.arch }}.zip diff --git a/.github/workflows/changelog-checker.yml b/.github/workflows/changelog-checker.yml index 40c9b17c68..1eea4196e7 100644 --- a/.github/workflows/changelog-checker.yml +++ b/.github/workflows/changelog-checker.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 with: ref: ${{ github.event.pull_request.head.sha }} fetch-depth: 0 # by default the checkout action doesn't checkout all branches diff --git a/.github/workflows/jira-issues.yaml b/.github/workflows/jira-issues.yaml index bddc69c83f..700803a45f 100644 --- a/.github/workflows/jira-issues.yaml +++ b/.github/workflows/jira-issues.yaml @@ -15,7 +15,7 @@ jobs: name: Jira Community Issue sync steps: - name: Login - uses: atlassian/gajira-login@ca13f8850ea309cf44a6e4e0c49d9aa48ac3ca4c # v3 + uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} @@ -72,14 +72,14 @@ jobs: - name: Close ticket if: ( github.event.action == 'closed' || github.event.action == 'deleted' ) && steps.search.outputs.issue - uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 + uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "Closed" - name: Reopen ticket if: github.event.action == 'reopened' && steps.search.outputs.issue - uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 + uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "To Do" diff --git a/.github/workflows/jira-pr.yaml b/.github/workflows/jira-pr.yaml index 078365ac88..a285c4c176 100644 --- a/.github/workflows/jira-pr.yaml +++ b/.github/workflows/jira-pr.yaml @@ -13,7 +13,7 @@ jobs: name: Jira sync steps: - name: Login - uses: atlassian/gajira-login@ca13f8850ea309cf44a6e4e0c49d9aa48ac3ca4c # v3 + uses: atlassian/gajira-login@45fd029b9f1d6d8926c6f04175aa80c0e42c9026 # v3.0.1 env: JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} @@ -86,14 +86,14 @@ jobs: - name: Close ticket if: ( github.event.action == 'closed' || github.event.action == 'deleted' ) && steps.search.outputs.issue - uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 + uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "Closed" - name: Reopen ticket if: github.event.action == 'reopened' && steps.search.outputs.issue - uses: atlassian/gajira-transition@4749176faf14633954d72af7a44d7f2af01cc92b # v3 + uses: atlassian/gajira-transition@38fc9cd61b03d6a53dd35fcccda172fe04b36de3 # v3.0.1 with: issue: ${{ steps.search.outputs.issue }} transition: "To Do" diff --git a/.github/workflows/nightly-api-gateway-conformance.yml b/.github/workflows/nightly-api-gateway-conformance.yml deleted file mode 100644 index abeec34659..0000000000 --- a/.github/workflows/nightly-api-gateway-conformance.yml +++ /dev/null @@ -1,27 +0,0 @@ -# Dispatch to the consul-k8s-workflows with a nightly cron -name: nightly-api-gateway-conformance -on: - schedule: - # * is a special character in YAML so you have to quote this string - # Run nightly at 12AM UTC/8PM EST/5PM PST. - - cron: '0 0 * * *' - - -# these should be the only settings that you will ever need to change -env: - BRANCH: ${{ github.ref_name }} - CONTEXT: "nightly" - -jobs: - api-gateway-conformance: - name: api-gateway-conformance - runs-on: ubuntu-latest - steps: - - uses: benc-uk/workflow-dispatch@798e70c97009500150087d30d9f11c5444830385 # v1.2.2 - name: conformance - with: - workflow: api-gateway-conformance.yml - repo: hashicorp/consul-k8s-workflows - ref: main - token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - inputs: '{ "context":"${{ env.CONTEXT }}", "repository":"${{ github.repository }}", "branch":"${{ env.BRANCH }}", "sha":"${{ github.sha }}", "token":"${{ secrets.ELEVATED_GITHUB_TOKEN }}" }' diff --git a/CHANGELOG.md b/CHANGELOG.md index d9a4d76bef..490213300e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,10 @@ BREAKING CHANGES: SECURITY: * Upgrade to use Go 1.20.6 and `x/net/http` 0.12.0. - This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2642](https://github.com/hashicorp/consul-k8s/issues/2642)] +This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2642](https://github.com/hashicorp/consul-k8s/issues/2642)] * Upgrade to use Go 1.20.7 and `x/net` 0.13.0. - This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) - and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2710](https://github.com/hashicorp/consul-k8s/issues/2710)] +This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) +and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2710](https://github.com/hashicorp/consul-k8s/issues/2710)] FEATURES: @@ -45,88 +45,15 @@ BUG FIXES: * api-gateway: Fix creation of invalid Kubernetes Service when multiple Gateway listeners have the same port. [[GH-2413](https://github.com/hashicorp/consul-k8s/issues/2413)] * api-gateway: fix helm install when setting copyAnnotations or nodeSelector [[GH-2597](https://github.com/hashicorp/consul-k8s/issues/2597)] * api-gateway: fixes bug where envoy will silently reject RSA keys less than 2048 bits in length when not in FIPS mode, and - will reject keys that are not 2048, 3072, or 4096 bits in length in FIPS mode. We now validate - and reject invalid certs earlier. [[GH-2478](https://github.com/hashicorp/consul-k8s/issues/2478)] +will reject keys that are not 2048, 3072, or 4096 bits in length in FIPS mode. We now validate +and reject invalid certs earlier. [[GH-2478](https://github.com/hashicorp/consul-k8s/issues/2478)] * api-gateway: set route condition appropriately when parent ref includes non-existent section name [[GH-2420](https://github.com/hashicorp/consul-k8s/issues/2420)] * control-plane: Always update ACL policies upon upgrade. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] * control-plane: fix bug in endpoints controller when deregistering services from consul when a node is deleted. [[GH-2571](https://github.com/hashicorp/consul-k8s/issues/2571)] * helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. [[GH-2652](https://github.com/hashicorp/consul-k8s/issues/2652)] * helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. [[GH-2687](https://github.com/hashicorp/consul-k8s/issues/2687)] * transparent-proxy: Fix issue where connect-inject lacked sufficient `mesh:write` privileges in some deployments, - which prevented virtual IPs from persisting properly. [[GH-2520](https://github.com/hashicorp/consul-k8s/issues/2520)] - -## 1.1.4 (Aug 10, 2023) - -SECURITY: - -* Upgrade to use Go 1.20.6 and `x/net/http` 0.12.0. - This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2642](https://github.com/hashicorp/consul-k8s/issues/2642)] -* Upgrade to use Go 1.20.7 and `x/net` 0.13.0. - This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) - and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2710](https://github.com/hashicorp/consul-k8s/issues/2710)] - -IMPROVEMENTS: - -* Add support to provide the logLevel flag via helm for multiple low level components. Introduces the following fields -1. `global.acls.logLevel` -2. `global.tls.logLevel` -3. `global.federation.logLevel` -4. `global.gossipEncryption.logLevel` -5. `server.logLevel` -6. `client.logLevel` -7. `meshGateway.logLevel` -8. `ingressGateways.logLevel` -9. `terminatingGateways.logLevel` -10. `telemetryCollector.logLevel` [[GH-2302](https://github.com/hashicorp/consul-k8s/issues/2302)] -* control-plane: increase timeout after login for ACL replication to 60 seconds [[GH-2656](https://github.com/hashicorp/consul-k8s/issues/2656)] -* helm: adds values for `securityContext` and `annotations` on TLS and ACL init/cleanup jobs. [[GH-2525](https://github.com/hashicorp/consul-k8s/issues/2525)] -* helm: do not set container securityContexts by default on OpenShift < 4.11 [[GH-2678](https://github.com/hashicorp/consul-k8s/issues/2678)] -* helm: set container securityContexts to match the `restricted` Pod Security Standards policy to support running Consul in a namespace with restricted PSA enforcement enabled [[GH-2572](https://github.com/hashicorp/consul-k8s/issues/2572)] - -BUG FIXES: - -* control-plane: fix bug in endpoints controller when deregistering services from consul when a node is deleted. [[GH-2571](https://github.com/hashicorp/consul-k8s/issues/2571)] -* helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. [[GH-2652](https://github.com/hashicorp/consul-k8s/issues/2652)] -* helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. [[GH-2687](https://github.com/hashicorp/consul-k8s/issues/2687)] - -## 1.0.9 (Aug 10, 2023) - -SECURITY: - -* Upgrade to use Go 1.19.11 and `x/net/http` 0.12.0. - This resolves [CVE-2023-29406](https://github.com/advisories/GHSA-f8f7-69v5-w4vx)(`net/http`). [[GH-2650](https://github.com/hashicorp/consul-k8s/issues/2650)] -* Upgrade to use Go 1.19.12 and `x/net` 0.13.0. - This resolves [CVE-2023-29409](https://nvd.nist.gov/vuln/detail/CVE-2023-29409)(`crypto/tls`) - and [CVE-2023-3978](https://nvd.nist.gov/vuln/detail/CVE-2023-3978)(`net/html`). [[GH-2717](https://github.com/hashicorp/consul-k8s/issues/2717)] - -IMPROVEMENTS: - -* Add support to provide the logLevel flag via helm for multiple low level components. Introduces the following fields -1. `global.acls.logLevel` -2. `global.tls.logLevel` -3. `global.federation.logLevel` -4. `global.gossipEncryption.logLevel` -5. `server.logLevel` -6. `client.logLevel` -7. `meshGateway.logLevel` -8. `ingressGateways.logLevel` -9. `terminatingGateways.logLevel` [[GH-2302](https://github.com/hashicorp/consul-k8s/issues/2302)] -* control-plane: increase timeout after login for ACL replication to 60 seconds [[GH-2656](https://github.com/hashicorp/consul-k8s/issues/2656)] -* helm: adds values for `securityContext` and `annotations` on TLS and ACL init/cleanup jobs. [[GH-2525](https://github.com/hashicorp/consul-k8s/issues/2525)] -* helm: do not set container securityContexts by default on OpenShift < 4.11 [[GH-2678](https://github.com/hashicorp/consul-k8s/issues/2678)] -* helm: set container securityContexts to match the `restricted` Pod Security Standards policy to support running Consul in a namespace with restricted PSA enforcement enabled [[GH-2572](https://github.com/hashicorp/consul-k8s/issues/2572)] - -BUG FIXES: - -* control-plane: fix bug in endpoints controller when deregistering services from consul when a node is deleted. [[GH-2571](https://github.com/hashicorp/consul-k8s/issues/2571)] -* helm: fix CONSUL_LOGIN_DATACENTER for consul client-daemonset. [[GH-2652](https://github.com/hashicorp/consul-k8s/issues/2652)] -* helm: fix ui ingress manifest formatting, and exclude `ingressClass` when not defined. [[GH-2687](https://github.com/hashicorp/consul-k8s/issues/2687)] - -## 0.49.8 (July 12, 2023) - -IMPROVEMENTS: - -* helm: Add `connectInject.prepareDataplanesUpgrade` setting for help upgrading to dataplanes. This setting is required if upgrading from non-dataplanes to dataplanes when ACLs are enabled. See https://developer.hashicorp.com/consul/docs/k8s/upgrade#upgrading-to-consul-dataplane for more information. [[GH-2514](https://github.com/hashicorp/consul-k8s/issues/2514)] +which prevented virtual IPs from persisting properly. [[GH-2520](https://github.com/hashicorp/consul-k8s/issues/2520)] ## 1.2.0 (June 28, 2023) @@ -176,89 +103,6 @@ BUG FIXES: * control-plane: Fix casing of the Enforce Consecutive 5xx field on Service Defaults and acceptance test fixtures. [[GH-2266](https://github.com/hashicorp/consul-k8s/issues/2266)] * control-plane: fix issue where consul-connect-injector acl token was unintentionally being deleted and not recreated when a container was restarted due to a livenessProbe failure. [[GH-1914](https://github.com/hashicorp/consul-k8s/issues/1914)] -## 1.1.3 (June 28, 2023) -BREAKING CHANGES: - -* control-plane: All policies managed by consul-k8s will now be updated on upgrade. If you previously edited the policies after install, your changes will be overwritten. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] - -SECURITY: - -* Bump Dockerfile base image to `alpine:3.18`. Resolves [CVE-2023-2650](https://github.com/advisories/GHSA-gqxg-9vfr-p9cg) vulnerability in openssl@3.0.8-r4 [[GH-2284](https://github.com/hashicorp/consul-k8s/issues/2284)] -* Update [Go-Discover](https://github.com/hashicorp/go-discover) in the container has been updated to address [CVE-2020-14040](https://github.com/advisories/GHSA-5rcv-m4m3-hfh7) [[GH-2390](https://github.com/hashicorp/consul-k8s/issues/2390)] - -FEATURES: - -* Add support for configuring graceful shutdown proxy lifecycle management settings. [[GH-2233](https://github.com/hashicorp/consul-k8s/issues/2233)] -* helm: Adds `acls.resources` field which can be configured to override the `resource` settings for the `server-acl-init` and `server-acl-init-cleanup` Jobs. [[GH-2416](https://github.com/hashicorp/consul-k8s/issues/2416)] -* sync-catalog: add ability to support weighted loadbalancing by service annotation `consul.hashicorp.com/service-weight: ` [[GH-2293](https://github.com/hashicorp/consul-k8s/issues/2293)] - -IMPROVEMENTS: - -* (Consul Enterprise) Add support to provide inputs via helm for audit log related configuration [[GH-2369](https://github.com/hashicorp/consul-k8s/issues/2369)] -* helm: Update the default amount of memory used by the connect-inject controller so that its less likely to get OOM killed. [[GH-2249](https://github.com/hashicorp/consul-k8s/issues/2249)] - -BUG FIXES: - -* control-plane: Always update ACL policies upon upgrade. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] -* control-plane: Fix casing of the Enforce Consecutive 5xx field on Service Defaults and acceptance test fixtures. [[GH-2266](https://github.com/hashicorp/consul-k8s/issues/2266)] - -## 1.0.8 (June 28, 2023) -BREAKING CHANGES: - -* control-plane: All policies managed by consul-k8s will now be updated on upgrade. If you previously edited the policies after install, your changes will be overwritten. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] - -SECURITY: - -* Bump Dockerfile base image for RedHat UBI `consul-k8s-control-plane` image to `ubi-minimal:9.2`. [[GH-2204](https://github.com/hashicorp/consul-k8s/issues/2204)] -* Bump Dockerfile base image to `alpine:3.18`. Resolves [CVE-2023-2650](https://github.com/advisories/GHSA-gqxg-9vfr-p9cg) vulnerability in openssl@3.0.8-r4 [[GH-2284](https://github.com/hashicorp/consul-k8s/issues/2284)] -* Bump `controller-runtime` to address CVEs in dependencies. [[GH-2225](https://github.com/hashicorp/consul-k8s/issues/2225)] -* Update [Go-Discover](https://github.com/hashicorp/go-discover) in the container has been updated to address [CVE-2020-14040](https://github.com/advisories/GHSA-5rcv-m4m3-hfh7) [[GH-2390](https://github.com/hashicorp/consul-k8s/issues/2390)] - -FEATURES: - -* Add support for configuring graceful shutdown proxy lifecycle management settings. [[GH-2233](https://github.com/hashicorp/consul-k8s/issues/2233)] -* helm: Adds `acls.resources` field which can be configured to override the `resource` settings for the `server-acl-init` and `server-acl-init-cleanup` Jobs. [[GH-2416](https://github.com/hashicorp/consul-k8s/issues/2416)] -* sync-catalog: add ability to support weighted loadbalancing by service annotation `consul.hashicorp.com/service-weight: ` [[GH-2293](https://github.com/hashicorp/consul-k8s/issues/2293)] - -IMPROVEMENTS: - -* (Consul Enterprise) Add support to provide inputs via helm for audit log related configuration [[GH-2265](https://github.com/hashicorp/consul-k8s/issues/2265)] -* helm: Update the default amount of memory used by the connect-inject controller so that its less likely to get OOM killed. [[GH-2249](https://github.com/hashicorp/consul-k8s/issues/2249)] - -BUG FIXES: - -* control-plane: Always update ACL policies upon upgrade. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] -* control-plane: Fix casing of the Enforce Consecutive 5xx field on Service Defaults and acceptance test fixtures. [[GH-2266](https://github.com/hashicorp/consul-k8s/issues/2266)] -* control-plane: add support for idleTimeout in the Service Router config [[GH-2156](https://github.com/hashicorp/consul-k8s/issues/2156)] -* control-plane: fix issue with json tags of service defaults fields EnforcingConsecutive5xx, MaxEjectionPercent and BaseEjectionTime. [[GH-2159](https://github.com/hashicorp/consul-k8s/issues/2159)] -* control-plane: fix issue with multiport pods crashlooping due to dataplane port conflicts by ensuring dns redirection is disabled for non-tproxy pods [[GH-2176](https://github.com/hashicorp/consul-k8s/issues/2176)] -* crd: fix bug on service intentions CRD causing some updates to be ignored. [[GH-2194](https://github.com/hashicorp/consul-k8s/issues/2194)] - - -## 0.49.7 (June 28, 2023) -BREAKING CHANGES: - -* control-plane: All policies managed by consul-k8s will now be updated on upgrade. If you previously edited the policies after install, your changes will be overwritten. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] - -SECURITY: - -* Bump Dockerfile base image for RedHat UBI `consul-k8s-control-plane` image to `ubi-minimal:9.2`. [[GH-2204](https://github.com/hashicorp/consul-k8s/issues/2204)] -* Bump Dockerfile base image to `alpine:3.18`. Resolves [CVE-2023-2650](https://github.com/advisories/GHSA-gqxg-9vfr-p9cg) vulnerability in openssl@3.0.8-r4 [[GH-2284](https://github.com/hashicorp/consul-k8s/issues/2284)] - -FEATURES: - -* helm: Adds `acls.resources` field which can be configured to override the `resource` settings for the `server-acl-init` and `server-acl-init-cleanup` Jobs. [[GH-2416](https://github.com/hashicorp/consul-k8s/issues/2416)] - -IMPROVEMENTS: - -* (Consul Enterprise) Add support to provide inputs via helm for audit log related configuration [[GH-2265](https://github.com/hashicorp/consul-k8s/issues/2265)] -* helm: Update the default amount of memory used by the connect-inject controller so that its less likely to get OOM killed. [[GH-2249](https://github.com/hashicorp/consul-k8s/issues/2249)] - -BUG FIXES: - -* control-plane: Always update ACL policies upon upgrade. [[GH-2392](https://github.com/hashicorp/consul-k8s/issues/2392)] -* crd: fix bug on service intentions CRD causing some updates to be ignored. [[GH-2194](https://github.com/hashicorp/consul-k8s/issues/2194)] - ## 1.1.2 (June 5, 2023) SECURITY: diff --git a/Makefile b/Makefile index 866a37fbfc..8facd3dbc8 100644 --- a/Makefile +++ b/Makefile @@ -183,7 +183,7 @@ ifeq (, $(shell which controller-gen)) CONTROLLER_GEN_TMP_DIR=$$(mktemp -d) ;\ cd $$CONTROLLER_GEN_TMP_DIR ;\ go mod init tmp ;\ - go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0 ;\ + go install sigs.k8s.io/controller-tools/cmd/controller-gen@v0.12.0 ;\ rm -rf $$CONTROLLER_GEN_TMP_DIR ;\ } CONTROLLER_GEN=$(shell go env GOPATH)/bin/controller-gen diff --git a/acceptance/framework/connhelper/connect_helper.go b/acceptance/framework/connhelper/connect_helper.go index 314c0d853a..f5ee134b04 100644 --- a/acceptance/framework/connhelper/connect_helper.go +++ b/acceptance/framework/connhelper/connect_helper.go @@ -26,6 +26,7 @@ import ( const ( StaticClientName = "static-client" StaticServerName = "static-server" + JobName = "job-client" ) // ConnectHelper configures a Consul cluster for connect injection tests. @@ -109,7 +110,7 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { // deployments because golang will execute them in reverse order // (i.e. the last registered cleanup function will be executed first). t.Cleanup(func() { - retrier := &retry.Timer{Timeout: 30 * time.Second, Wait: 100 * time.Millisecond} + retrier := &retry.Timer{Timeout: 60 * time.Second, Wait: 100 * time.Millisecond} retry.RunWith(retrier, t, func(r *retry.R) { tokens, _, err := c.ConsulClient.ACL().TokenList(nil) require.NoError(r, err) @@ -170,6 +171,82 @@ func (c *ConnectHelper) DeployClientAndServer(t *testing.T) { }) } +// DeployJob deploys a job pod to the Kubernetes +// cluster which will be used to test service mesh connectivity. If the Secure +// flag is true, a pre-check is done to ensure that the ACL tokens for the test +// are deleted. The status of the deployment and injection is checked after the +// deployment is complete to ensure success. +func (c *ConnectHelper) DeployJob(t *testing.T, path string) { + // Check that the ACL token is deleted. + if c.Secure { + // We need to register the cleanup function before we create the + // deployments because golang will execute them in reverse order + // (i.e. the last registered cleanup function will be executed first). + t.Cleanup(func() { + retrier := &retry.Timer{Timeout: 30 * time.Second, Wait: 100 * time.Millisecond} + retry.RunWith(retrier, t, func(r *retry.R) { + tokens, _, err := c.ConsulClient.ACL().TokenList(nil) + require.NoError(r, err) + for _, token := range tokens { + require.NotContains(r, token.Description, JobName) + } + }) + }) + } + + logger.Log(t, "creating job-client deployment") + k8s.DeployJob(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, path) + + // Check that job-client has been injected and + // now have 2 containers. + for _, labelSelector := range []string{"app=job-client"} { + podList, err := c.Ctx.KubernetesClient(t).CoreV1().Pods(c.Ctx.KubectlOptions(t).Namespace).List(context.Background(), metav1.ListOptions{ + LabelSelector: labelSelector, + }) + require.NoError(t, err) + require.Len(t, podList.Items, 1) + require.Len(t, podList.Items[0].Spec.Containers, 2) + } +} + +// DeployServer deploys a server pod to the Kubernetes +// cluster which will be used to test service mesh connectivity. If the Secure +// flag is true, a pre-check is done to ensure that the ACL tokens for the test +// are deleted. The status of the deployment and injection is checked after the +// deployment is complete to ensure success. +func (c *ConnectHelper) DeployServer(t *testing.T) { + // Check that the ACL token is deleted. + if c.Secure { + // We need to register the cleanup function before we create the + // deployments because golang will execute them in reverse order + // (i.e. the last registered cleanup function will be executed first). + t.Cleanup(func() { + retrier := &retry.Timer{Timeout: 30 * time.Second, Wait: 100 * time.Millisecond} + retry.RunWith(retrier, t, func(r *retry.R) { + tokens, _, err := c.ConsulClient.ACL().TokenList(nil) + require.NoError(r, err) + for _, token := range tokens { + require.NotContains(r, token.Description, StaticServerName) + } + }) + }) + } + + logger.Log(t, "creating static-server deployment") + k8s.DeployKustomize(t, c.Ctx.KubectlOptions(t), c.Cfg.NoCleanupOnFailure, c.Cfg.NoCleanup, c.Cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + + // Check that static-server has been injected and + // now have 2 containers. + for _, labelSelector := range []string{"app=static-server"} { + podList, err := c.Ctx.KubernetesClient(t).CoreV1().Pods(c.Ctx.KubectlOptions(t).Namespace).List(context.Background(), metav1.ListOptions{ + LabelSelector: labelSelector, + }) + require.NoError(t, err) + require.Len(t, podList.Items, 1) + require.Len(t, podList.Items[0].Spec.Containers, 2) + } +} + // SetupAppNamespace creates a namespace where applications are deployed. This // does nothing if UseAppNamespace is not set. The app namespace is relevant // when testing with restricted PSA enforcement enabled. @@ -215,26 +292,36 @@ func (c *ConnectHelper) CreateResolverRedirect(t *testing.T) { // TestConnectionFailureWithoutIntention ensures the connection to the static // server fails when no intentions are configured. -func (c *ConnectHelper) TestConnectionFailureWithoutIntention(t *testing.T) { +func (c *ConnectHelper) TestConnectionFailureWithoutIntention(t *testing.T, clientType ...string) { logger.Log(t, "checking that the connection is not successful because there's no intention") opts := c.KubectlOptsForApp(t) + //Default to deploying static-client. If a client type is passed in (ex. job-client), use that instead. + client := StaticClientName + if len(clientType) > 0 { + client = clientType[0] + } if c.Cfg.EnableTransparentProxy { - k8s.CheckStaticServerConnectionFailing(t, opts, StaticClientName, "http://static-server") + k8s.CheckStaticServerConnectionFailing(t, opts, client, "http://static-server") } else { - k8s.CheckStaticServerConnectionFailing(t, opts, StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionFailing(t, opts, client, "http://localhost:1234") } } // CreateIntention creates an intention for the static-server pod to connect to // the static-client pod. -func (c *ConnectHelper) CreateIntention(t *testing.T) { +func (c *ConnectHelper) CreateIntention(t *testing.T, clientType ...string) { logger.Log(t, "creating intention") + //Default to deploying static-client. If a client type is passed in (ex. job-client), use that instead. + client := StaticClientName + if len(clientType) > 0 { + client = clientType[0] + } _, _, err := c.ConsulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ Kind: api.ServiceIntentions, Name: StaticServerName, Sources: []*api.SourceIntention{ { - Name: StaticClientName, + Name: client, Action: api.IntentionActionAllow, }, }, @@ -244,14 +331,19 @@ func (c *ConnectHelper) CreateIntention(t *testing.T) { // TestConnectionSuccess ensures the static-server pod can connect to the // static-client pod once the intention is set. -func (c *ConnectHelper) TestConnectionSuccess(t *testing.T) { +func (c *ConnectHelper) TestConnectionSuccess(t *testing.T, clientType ...string) { logger.Log(t, "checking that connection is successful") opts := c.KubectlOptsForApp(t) + //Default to deploying static-client. If a client type is passed in (ex. job-client), use that instead. + client := StaticClientName + if len(clientType) > 0 { + client = clientType[0] + } if c.Cfg.EnableTransparentProxy { // todo: add an assertion that the traffic is going through the proxy - k8s.CheckStaticServerConnectionSuccessful(t, opts, StaticClientName, "http://static-server") + k8s.CheckStaticServerConnectionSuccessful(t, opts, client, "http://static-server") } else { - k8s.CheckStaticServerConnectionSuccessful(t, opts, StaticClientName, "http://localhost:1234") + k8s.CheckStaticServerConnectionSuccessful(t, opts, client, "http://localhost:1234") } } diff --git a/acceptance/framework/flags/flags.go b/acceptance/framework/flags/flags.go index ce8e1ea726..9f1e3e15aa 100644 --- a/acceptance/framework/flags/flags.go +++ b/acceptance/framework/flags/flags.go @@ -35,13 +35,13 @@ type TestFlags struct { flagHelmChartVersion string flagConsulImage string flagConsulK8sImage string - flagConsulDataplaneImage string flagConsulVersion string - flagConsulDataplaneVersion string flagEnvoyImage string flagConsulCollectorImage string flagVaultHelmChartVersion string flagVaultServerVersion string + flagConsulDataplaneImage string + flagConsulDataplaneVersion string flagHCPResourceID string @@ -198,7 +198,6 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { kubeEnvs := config.NewKubeTestConfigList(t.flagKubeconfigs, t.flagKubecontexts, t.flagKubeNamespaces) c := &config.TestConfig{ - EnableEnterprise: t.flagEnableEnterprise, EnterpriseLicense: t.flagEnterpriseLicense, @@ -219,15 +218,14 @@ func (t *TestFlags) TestConfigFromFlags() *config.TestConfig { HelmChartVersion: t.flagHelmChartVersion, ConsulImage: t.flagConsulImage, ConsulK8SImage: t.flagConsulK8sImage, - ConsulDataplaneImage: t.flagConsulDataplaneImage, ConsulVersion: consulVersion, - ConsulDataplaneVersion: consulDataplaneVersion, EnvoyImage: t.flagEnvoyImage, ConsulCollectorImage: t.flagConsulCollectorImage, VaultHelmChartVersion: t.flagVaultHelmChartVersion, VaultServerVersion: t.flagVaultServerVersion, - - HCPResourceID: t.flagHCPResourceID, + ConsulDataplaneImage: t.flagConsulDataplaneImage, + ConsulDataplaneVersion: consulDataplaneVersion, + HCPResourceID: t.flagHCPResourceID, NoCleanupOnFailure: t.flagNoCleanupOnFailure, NoCleanup: t.flagNoCleanup, diff --git a/acceptance/framework/k8s/deploy.go b/acceptance/framework/k8s/deploy.go index 828586c8cf..e60f4c4730 100644 --- a/acceptance/framework/k8s/deploy.go +++ b/acceptance/framework/k8s/deploy.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/stretchr/testify/require" v1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" "k8s.io/apimachinery/pkg/util/yaml" ) @@ -72,6 +73,32 @@ func DeployKustomize(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailu RunKubectl(t, options, "wait", "--for=condition=available", "--timeout=5m", fmt.Sprintf("deploy/%s", deployment.Name)) } +func DeployJob(t *testing.T, options *k8s.KubectlOptions, noCleanupOnFailure bool, noCleanup bool, debugDirectory, kustomizeDir string) { + t.Helper() + + KubectlApplyK(t, options, kustomizeDir) + + output, err := RunKubectlAndGetOutputE(t, options, "kustomize", kustomizeDir) + require.NoError(t, err) + + job := batchv1.Job{} + err = yaml.NewYAMLOrJSONDecoder(strings.NewReader(output), 1024).Decode(&job) + require.NoError(t, err) + + helpers.Cleanup(t, noCleanupOnFailure, noCleanup, func() { + // Note: this delete command won't wait for pods to be fully terminated. + // This shouldn't cause any test pollution because the underlying + // objects are deployments, and so when other tests create these + // they should have different pod names. + WritePodsDebugInfoIfFailed(t, options, debugDirectory, labelMapToString(job.GetLabels())) + KubectlDeleteK(t, options, kustomizeDir) + }) + logger.Log(t, "job deployed") + + // Because Jobs don't have a "started" condition, we have to check the status of the Pods they create. + RunKubectl(t, options, "wait", "--for=condition=Ready", "--timeout=5m", "pods", "--selector", fmt.Sprintf("job-name=%s", job.Name)) +} + // CheckStaticServerConnection execs into a pod of sourceApp // and runs a curl command with the provided curlArgs. // This function assumes that the connection is made to the static-server and expects the output @@ -93,7 +120,10 @@ func CheckStaticServerConnection(t *testing.T, options *k8s.KubectlOptions, sour // on the existence of any of them. func CheckStaticServerConnectionMultipleFailureMessages(t *testing.T, options *k8s.KubectlOptions, sourceApp string, expectSuccess bool, failureMessages []string, expectedSuccessOutput string, curlArgs ...string) { t.Helper() - + resourceType := "deploy/" + if sourceApp == "job-client" { + resourceType = "jobs/" + } expectedOutput := "hello world" if expectedSuccessOutput != "" { expectedOutput = expectedSuccessOutput @@ -101,7 +131,7 @@ func CheckStaticServerConnectionMultipleFailureMessages(t *testing.T, options *k retrier := &retry.Timer{Timeout: 320 * time.Second, Wait: 2 * time.Second} - args := []string{"exec", "deploy/" + sourceApp, "-c", sourceApp, "--", "curl", "-vvvsSf"} + args := []string{"exec", resourceType + sourceApp, "-c", sourceApp, "--", "curl", "-vvvsSf"} args = append(args, curlArgs...) retry.RunWith(retrier, t, func(r *retry.R) { diff --git a/acceptance/framework/vault/vault_cluster.go b/acceptance/framework/vault/vault_cluster.go index 8b82e41841..68e41eb238 100644 --- a/acceptance/framework/vault/vault_cluster.go +++ b/acceptance/framework/vault/vault_cluster.go @@ -6,8 +6,6 @@ package vault import ( "context" "fmt" - "os" - "strings" "testing" "time" @@ -15,7 +13,6 @@ import ( terratestk8s "github.com/gruntwork-io/terratest/modules/k8s" terratestLogger "github.com/gruntwork-io/terratest/modules/logger" "github.com/hashicorp/consul-k8s/acceptance/framework/config" - "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/environment" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" @@ -58,32 +55,12 @@ func NewVaultCluster(t *testing.T, ctx environment.TestContext, cfg *config.Test logger := terratestLogger.New(logger.TestLogger{}) kopts := ctx.KubectlOptions(t) - ns := ctx.KubectlOptions(t).Namespace - - entstr := "-ent" values := defaultHelmValues(releaseName) if cfg.EnablePodSecurityPolicies { values["global.psp.enable"] = "true" } - vaultReleaseName := helpers.RandomName() - k8sClient := environment.KubernetesClientFromOptions(t, ctx.KubectlOptions(t)) - vaultLicenseSecretName := fmt.Sprintf("%s-enterprise-license", vaultReleaseName) - vaultLicenseSecretKey := "license" - - vaultEnterpriseLicense := os.Getenv("VAULT_LICENSE") - if cfg.VaultServerVersion != "" { - - if strings.Contains(cfg.VaultServerVersion, entstr) { - - logger.Logf(t, "Creating secret for Vault license") - consul.CreateK8sSecret(t, k8sClient, cfg, ns, vaultLicenseSecretName, vaultLicenseSecretKey, vaultEnterpriseLicense) - - values["server.image.repository"] = "docker.mirror.hashicorp.services/hashicorp/vault-enterprise" - values["server.enterpriseLicense.secretName"] = vaultLicenseSecretName - values["server.enterpriseLicense.secretKey"] = vaultLicenseSecretKey - } values["server.image.tag"] = cfg.VaultServerVersion } vaultHelmChartVersion := defaultVaultHelmChartVersion diff --git a/acceptance/go.mod b/acceptance/go.mod index 1dd344a5c8..2da38c70b7 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -4,12 +4,11 @@ go 1.20 require ( github.com/gruntwork-io/terratest v0.31.2 - github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230609143603-198c4433d892 + github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230724205934-5b57e6340dff github.com/hashicorp/consul/api v1.22.0-rc1 github.com/hashicorp/consul/sdk v0.14.0-rc1 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/go-version v1.6.0 - github.com/hashicorp/hcp-sdk-go v0.50.0 github.com/hashicorp/serf v0.10.1 github.com/hashicorp/vault/api v1.8.3 github.com/stretchr/testify v1.8.3 @@ -25,7 +24,6 @@ require ( require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/armon/go-radix v1.0.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/aws/aws-sdk-go v1.44.262 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect @@ -41,18 +39,9 @@ require ( github.com/ghodss/yaml v1.0.0 // indirect github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.2.3 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.3 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.1 // indirect - github.com/go-openapi/loads v0.21.2 // indirect - github.com/go-openapi/runtime v0.25.0 // indirect - github.com/go-openapi/spec v0.20.8 // indirect - github.com/go-openapi/strfmt v0.21.3 // indirect github.com/go-openapi/swag v0.22.3 // indirect - github.com/go-openapi/validate v0.22.1 // indirect - github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect github.com/go-sql-driver/mysql v1.5.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.3 // indirect @@ -88,7 +77,6 @@ require ( github.com/mattn/go-isatty v0.0.17 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/miekg/dns v1.1.50 // indirect - github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.0 // indirect @@ -100,8 +88,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oklog/run v1.0.0 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -112,18 +98,14 @@ require ( github.com/prometheus/procfs v0.8.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect - github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/urfave/cli v1.22.2 // indirect - go.mongodb.org/mongo-driver v1.11.0 // indirect - go.opentelemetry.io/otel v1.11.1 // indirect - go.opentelemetry.io/otel/trace v1.11.1 // indirect go.uber.org/atomic v1.9.0 // indirect golang.org/x/crypto v0.11.0 // indirect golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53 // indirect golang.org/x/mod v0.9.0 // indirect golang.org/x/net v0.13.0 // indirect - golang.org/x/oauth2 v0.6.0 // indirect + golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect golang.org/x/sys v0.10.0 // indirect golang.org/x/term v0.10.0 // indirect golang.org/x/text v0.11.0 // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index 7361efbbb6..0f33cfadc8 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -91,9 +91,6 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.16.26/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -217,88 +214,31 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= -github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= -github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= -github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= -github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= -github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= -github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= -github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE= -github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -337,7 +277,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -352,7 +291,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -397,8 +335,8 @@ github.com/gruntwork-io/gruntwork-cli v0.7.0 h1:YgSAmfCj9c61H+zuvHwKfYUwlMhu5arn github.com/gruntwork-io/gruntwork-cli v0.7.0/go.mod h1:jp6Z7NcLF2avpY8v71fBx6hds9eOFPELSuD/VPv7w00= github.com/gruntwork-io/terratest v0.31.2 h1:xvYHA80MUq5kx670dM18HInewOrrQrAN+XbVVtytUHg= github.com/gruntwork-io/terratest v0.31.2/go.mod h1:EEgJie28gX/4AD71IFqgMj6e99KP5mi81hEtzmDjxTo= -github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230609143603-198c4433d892 h1:4iI0ztWbVPTSDax+m1/XDs4jIRorxY4kSMyuM0fX+Dc= -github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230609143603-198c4433d892/go.mod h1:iZ8BJGSnY52wnxJTo2VIfGX63CPjqiNzbuqdOtJCKnI= +github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230724205934-5b57e6340dff h1:E5o8N01LGheJfgXAbFgjXd37DgnT7MmfeUnmXFMgSuc= +github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230724205934-5b57e6340dff/go.mod h1:stDdIOMKKlo8hZMViCPPNiLCNuYea2eQofHzOPZUz/o= github.com/hashicorp/consul/api v1.22.0-rc1 h1:ePmGqndeMgaI38KUbSA/CqTzeEAIogXyWnfNJzglo70= github.com/hashicorp/consul/api v1.22.0-rc1/go.mod h1:wtduXtbAqSGtBdi3tyA5SSAYGAG51rBejV9SEUBciMY= github.com/hashicorp/consul/sdk v0.14.0-rc1 h1:PuETOfN0uxl28i0Pq6rK7TBCrIl7psMbL0YTSje4KvM= @@ -455,8 +393,6 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcp-sdk-go v0.50.0 h1:vOUpVf4MQF/gtoBukuoYKs/i6KinTSpP5jhKCvsZ2bc= -github.com/hashicorp/hcp-sdk-go v0.50.0/go.mod h1:hZqky4HEzsKwvLOt4QJlZUrjeQmb4UCZUhDP2HyQFfc= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= @@ -485,7 +421,6 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= @@ -503,13 +438,10 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -528,11 +460,8 @@ github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -563,8 +492,6 @@ github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= -github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -574,7 +501,6 @@ github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -592,7 +518,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= @@ -600,11 +525,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -619,14 +541,11 @@ github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E= github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -676,8 +595,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uY github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rubiojr/go-vhd v0.0.0-20160810183302-0bfd3b39853c/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= @@ -695,12 +612,9 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUt github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= -github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -726,7 +640,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= @@ -734,8 +647,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -745,14 +656,8 @@ github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vdemeester/k8s-pkg-credentialprovider v0.0.0-20200107171650-7c61ffa44238/go.mod h1:JwQJCMWpUDqjZrB5jpw0f5VbN7U95zxFy1ZDpoEarGo= github.com/vmware/govmomi v0.20.3/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -761,21 +666,11 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= -go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= -go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= -go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs= -go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= -go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= @@ -788,7 +683,6 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -796,10 +690,8 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191206172530-e9b2fee46413/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -879,10 +771,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -895,14 +785,12 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -924,13 +812,10 @@ golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -969,7 +854,6 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1019,13 +903,9 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -1176,7 +1056,6 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= @@ -1203,9 +1082,7 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= @@ -1233,7 +1110,7 @@ k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ= k8s.io/cloud-provider v0.17.0/go.mod h1:Ze4c3w2C0bRsjkBUoHpFi+qWe3ob1wI2/7cUn+YQIDE= k8s.io/code-generator v0.0.0-20191121015212-c4c8f8345c7e/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= k8s.io/component-base v0.17.0/go.mod h1:rKuRAokNMY2nn2A6LP/MiwpoaMRHpfRnrPaUJJj1Yoc= -k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4= +k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g= k8s.io/csi-translation-lib v0.17.0/go.mod h1:HEF7MEz7pOLJCnxabi45IPkhSsE/KmxPQksuCrHKWls= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190822140433-26a664648505/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= diff --git a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go index 89ba07a1e7..22faf55529 100644 --- a/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go +++ b/acceptance/tests/api-gateway/api_gateway_gatewayclassconfig_test.go @@ -63,7 +63,7 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { k8sClient := ctx.ControllerRuntimeClient(t) - // create a GatewayClassConfig with configuration set + // Create a GatewayClassConfig. gatewayClassConfigName := "gateway-class-config" gatewayClassConfig := &v1alpha1.GatewayClassConfig{ ObjectMeta: metav1.ObjectMeta{ @@ -127,7 +127,6 @@ func TestAPIGateway_GatewayClassConfig(t *testing.T) { gatewayName := "gcctestgateway" + namespace logger.Log(t, "creating controlled gateway") gateway := createGateway(t, k8sClient, gatewayName, namespace, gatewayClassName, certificateName) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { logger.Log(t, "deleting all gateways") k8sClient.DeleteAllOf(context.Background(), &gwv1beta1.Gateway{}, client.InNamespace(namespace)) diff --git a/acceptance/tests/api-gateway/api_gateway_test.go b/acceptance/tests/api-gateway/api_gateway_test.go index df4a097b7e..721bbf2527 100644 --- a/acceptance/tests/api-gateway/api_gateway_test.go +++ b/acceptance/tests/api-gateway/api_gateway_test.go @@ -126,7 +126,7 @@ func TestAPIGateway_Basic(t *testing.T) { // On startup, the controller can take upwards of 1m to perform // leader election so we may need to wait a long time for - // the reconcile loop to run (hence the timeout here). + // the reconcile loop to run (hence the 1m timeout here). var gatewayAddress string counter := &retry.Counter{Count: 120, Wait: 2 * time.Second} retry.RunWith(counter, t, func(r *retry.R) { @@ -288,257 +288,6 @@ func TestAPIGateway_Basic(t *testing.T) { } } -func TestAPIGateway_JWTAuth_Basic(t *testing.T) { - t.Skip("skipping this test until GW JWT auth is complete") - ctx := suite.Environment().DefaultContext(t) - cfg := suite.Config() - - if !cfg.EnableEnterprise { - t.Skipf("skipping this test because -enable-enterprise is not set") - } - - helmValues := map[string]string{ - "connectInject.enabled": "true", - "connectInject.consulNamespaces.mirroringK8S": "true", - "global.acls.manageSystemACLs": "true", // acls must be enabled for JWT auth to take place - "global.tls.enabled": "true", - "global.logLevel": "trace", - } - - releaseName := helpers.RandomName() - consulCluster := consul.NewHelmCluster(t, helmValues, ctx, cfg, releaseName) - - consulCluster.Create(t) - - // Override the default proxy config settings for this test - consulClient, _ := consulCluster.SetupConsulClient(t, true) - _, _, err := consulClient.ConfigEntries().Set(&api.ProxyConfigEntry{ - Kind: api.ProxyDefaults, - Name: api.ProxyConfigGlobal, - Config: map[string]interface{}{ - "protocol": "http", - }, - }, nil) - require.NoError(t, err) - - logger.Log(t, "creating api-gateway resources") - out, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-k", "../fixtures/cases/api-gateways/jwt-auth") - require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { - // Ignore errors here because if the test ran as expected - // the custom resources will have been deleted. - k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-k", "../fixtures/cases/api-gateways/jwt-auth") - }) - - // Create certificate secret, we do this separately since - // applying the secret will make an invalid certificate that breaks other tests - logger.Log(t, "creating certificate secret") - out, err = k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "apply", "-f", "../fixtures/bases/api-gateway/certificate.yaml") - require.NoError(t, err, out) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { - // Ignore errors here because if the test ran as expected - // the custom resources will have been deleted. - k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), "delete", "-f", "../fixtures/bases/api-gateway/certificate.yaml") - }) - - // patch certificate with data - logger.Log(t, "patching certificate secret with generated data") - certificate := generateCertificate(t, nil, "gateway.test.local") - k8s.RunKubectl(t, ctx.KubectlOptions(t), "patch", "secret", "certificate", "-p", fmt.Sprintf(`{"data":{"tls.crt":"%s","tls.key":"%s"}}`, base64.StdEncoding.EncodeToString(certificate.CertPEM), base64.StdEncoding.EncodeToString(certificate.PrivateKeyPEM)), "--type=merge") - - // We use the static-client pod so that we can make calls to the api gateway - // via kubectl exec without needing a route into the cluster from the test machine. - logger.Log(t, "creating static-client pod") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-client") - - k8s.RunKubectl(t, ctx.KubectlOptions(t), "wait", "--for=condition=available", "--timeout=5m", fmt.Sprintf("deploy/%s", "static-server")) - // Grab a kubernetes client so that we can verify binding - // behavior prior to issuing requests through the gateway. - k8sClient := ctx.ControllerRuntimeClient(t) - - // On startup, the controller can take upwards of 1m to perform - // leader election so we may need to wait a long time for - // the reconcile loop to run (hence the 2m timeout here). - var ( - gatewayAddress string - gatewayClass gwv1beta1.GatewayClass - httpRoute gwv1beta1.HTTPRoute - httpRouteAuth gwv1beta1.HTTPRoute - ) - - counter := &retry.Counter{Count: 60, Wait: 2 * time.Second} - retry.RunWith(counter, t, func(r *retry.R) { - var gateway gwv1beta1.Gateway - err := k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway", Namespace: "default"}, &gateway) - require.NoError(r, err) - - // check our finalizers - require.Len(r, gateway.Finalizers, 1) - require.EqualValues(r, gatewayFinalizer, gateway.Finalizers[0]) - - // check our statuses - checkStatusCondition(r, gateway.Status.Conditions, trueCondition("Accepted", "Accepted")) - checkStatusCondition(r, gateway.Status.Conditions, trueCondition("ConsulAccepted", "Accepted")) - require.Len(r, gateway.Status.Listeners, 4) - - require.EqualValues(r, 1, gateway.Status.Listeners[0].AttachedRoutes) - checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, trueCondition("Accepted", "Accepted")) - checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, falseCondition("Conflicted", "NoConflicts")) - checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) - require.EqualValues(r, 1, gateway.Status.Listeners[1].AttachedRoutes) - checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, trueCondition("Accepted", "Accepted")) - checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, falseCondition("Conflicted", "NoConflicts")) - checkStatusCondition(r, gateway.Status.Listeners[1].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) - - // check that we have an address to use - require.Len(r, gateway.Status.Addresses, 1) - // now we know we have an address, set it so we can use it - gatewayAddress = gateway.Status.Addresses[0].Value - - // gateway class checks - err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway-class"}, &gatewayClass) - require.NoError(r, err) - - // check our finalizers - require.Len(r, gatewayClass.Finalizers, 1) - require.EqualValues(r, gatewayClassFinalizer, gatewayClass.Finalizers[0]) - - // http route checks - err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "http-route", Namespace: "default"}, &httpRoute) - require.NoError(r, err) - - // http route checks - err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "http-route-auth", Namespace: "default"}, &httpRouteAuth) - require.NoError(r, err) - - // check our finalizers - require.Len(r, httpRoute.Finalizers, 1) - require.EqualValues(r, gatewayFinalizer, httpRoute.Finalizers[0]) - - // check parent status - require.Len(r, httpRoute.Status.Parents, 1) - require.EqualValues(r, gatewayClassControllerName, httpRoute.Status.Parents[0].ControllerName) - require.EqualValues(r, "gateway", httpRoute.Status.Parents[0].ParentRef.Name) - checkStatusCondition(r, httpRoute.Status.Parents[0].Conditions, trueCondition("Accepted", "Accepted")) - checkStatusCondition(r, httpRoute.Status.Parents[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) - checkStatusCondition(r, httpRoute.Status.Parents[0].Conditions, trueCondition("ConsulAccepted", "Accepted")) - - // check our finalizers - require.Len(r, httpRouteAuth.Finalizers, 1) - require.EqualValues(r, gatewayFinalizer, httpRouteAuth.Finalizers[0]) - - // check parent status - require.Len(r, httpRouteAuth.Status.Parents, 1) - require.EqualValues(r, gatewayClassControllerName, httpRouteAuth.Status.Parents[0].ControllerName) - require.EqualValues(r, "gateway", httpRouteAuth.Status.Parents[0].ParentRef.Name) - checkStatusCondition(r, httpRouteAuth.Status.Parents[0].Conditions, trueCondition("Accepted", "Accepted")) - checkStatusCondition(r, httpRouteAuth.Status.Parents[0].Conditions, trueCondition("ResolvedRefs", "ResolvedRefs")) - checkStatusCondition(r, httpRouteAuth.Status.Parents[0].Conditions, trueCondition("ConsulAccepted", "Accepted")) - }) - - // check that the Consul entries were created - entry, _, err := consulClient.ConfigEntries().Get(api.APIGateway, "gateway", nil) - require.NoError(t, err) - gateway := entry.(*api.APIGatewayConfigEntry) - - entry, _, err = consulClient.ConfigEntries().Get(api.HTTPRoute, "http-route", nil) - require.NoError(t, err) - consulHTTPRoute := entry.(*api.HTTPRouteConfigEntry) - - entry, _, err = consulClient.ConfigEntries().Get(api.HTTPRoute, "http-route-auth", nil) - require.NoError(t, err) - consulHTTPRouteAuth := entry.(*api.HTTPRouteConfigEntry) - - // now check the gateway status conditions - checkConsulStatusCondition(t, gateway.Status.Conditions, trueConsulCondition("Accepted", "Accepted")) - - // and the route status conditions - checkConsulStatusCondition(t, consulHTTPRoute.Status.Conditions, trueConsulCondition("Bound", "Bound")) - checkConsulStatusCondition(t, consulHTTPRouteAuth.Status.Conditions, trueConsulCondition("Bound", "Bound")) - - // finally we check that we can actually route to the service(s) via the gateway - k8sOptions := ctx.KubectlOptions(t) - targetHTTPAddress := fmt.Sprintf("http://%s/v1", gatewayAddress) - targetHTTPAddressAdmin := fmt.Sprintf("http://%s:8080/admin", gatewayAddress) - targetHTTPAddressPet := fmt.Sprintf("http://%s:8080/pet", gatewayAddress) - // valid JWT token with role of "doctor" - doctorToken := "eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzI1NiIsImtpZCI6IkMtRTFuQ2p3Z0JDLVB1R00yTzQ2N0ZSRGhLeDhBa1ZjdElTQWJvM3JpZXcifQ.eyJpc3MiOiJsb2NhbCIsInJvbGUiOiJkb2N0b3IifQ.FfgpzjMf8Evh6K-fJ1cLXklfIXOm-vojVbWlPPbGVFtzxZ9hxMxoyAY_G8i36SfGrpUlp-RJ6ohMvprMrEgyRgbenu7u5kkm5iGHW-zpMus4izXRxPELBcpWOGF105HIssT2NYRstXieNR8EVzvGfLdvR0GW8ttEERgseqGvuAfdb4-aNYsysGwUUHbsZjazA6H1rZmWqHdCLOJ2ZwFsIdckO9CadnkyTILpcPUmLYyUVJdtlLGOySb0GG8c_dPML_IR5jSXCSUZt6S2JBNBNBdqukrlqpA-fIaaWft0dbWVMhv8DqPC8znult8dKvLZ1qXeU0itsqqJUyE16ihJjw" - // valid JWT token with role of "pet" - petToken := "eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzI1NiIsImtpZCI6IkMtRTFuQ2p3Z0JDLVB1R00yTzQ2N0ZSRGhLeDhBa1ZjdElTQWJvM3JpZXcifQ.eyJpc3MiOiJsb2NhbCIsInJvbGUiOiJwZXQifQ.l94rJayGGTMB426HwEw5ipSjaIHjm-UWDHiBAlB_Slmi814AxAfl_0AdRwSz67UDnkoygKbvPpR5xUB03JCXNshLZuKLegWsBeQg_OJYvZGmFagl5NglBFvH7Jbta4e1eQoAxZI6Xyy1jHbu7jFBjQPVnK8EaRvWoW8Pe8a8rp_5xhub0pomhvRF6Pm5kAS4cMnxvqpVc5Oo5nO7ws_SmoNnbt2Ok14k23Zx5E2EWmGStOfbgFsdbhVbepB2DMzqv1j8jvBbwa_OxCwc_7pEOthOOxRV6L3ZjgbRSB4GumlXAOCBYXD1cRLgrMSrWB1GkefAKu8PV0Ho1px6sI9Evg" - - // check that intentions keep our connection from happening - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddress) - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddressAdmin) - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", doctorToken, targetHTTPAddressAdmin) - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", petToken, targetHTTPAddressAdmin) - - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddressPet) - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", doctorToken, targetHTTPAddressPet) - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", petToken, targetHTTPAddressPet) - - // Now we create the allow intention. - _, _, err = consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: "static-server", - Sources: []*api.SourceIntention{ - { - Name: "gateway", - Action: api.IntentionActionAllow, - }, - }, - }, nil) - require.NoError(t, err) - - _, _, err = consulClient.ConfigEntries().Set(&api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: "static-server-protected", - Sources: []*api.SourceIntention{ - { - Name: "gateway", - Action: api.IntentionActionAllow, - }, - }, - }, nil) - require.NoError(t, err) - - // Test that we can make a call to the api gateway - logger.Log(t, "trying calls to api gateway http") - k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, targetHTTPAddress) - - // ensure that overrides -> route extension -> default by making a request to the admin route with a JWT that has an issuer of "local" and a "role" of "doctor" - // we can see that: - // * the "iss" verification in the gateway override takes precedence over the "iss" verification in the route filter - // * the "role" verification in the route extension takes precedence over the "role" verification in the gateway default - // should fail because we're missing JWT - logger.Log(t, "trying calls to api gateway /admin should fail without JWT token") - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddressAdmin) - - // should fail because we use the token with the wrong role and correct issuer - logger.Log(t, "trying calls to api gateway /admin should fail with wrong role") - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", petToken, targetHTTPAddressAdmin) - - // will succeed because we use the token with the correct role and the correct issuer - logger.Log(t, "trying calls to api gateway /admin should succeed with JWT token with correct role") - k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, "-H", doctorToken, targetHTTPAddressAdmin) - - // ensure that overrides -> route extension -> default by making a request to the admin route with a JWT that has an issuer of "local" and a "role" of "pet" - // the route does not define - // we can see that: - // * the "iss" verification in the gateway override takes precedence over the "iss" verification in the route filter - // * the "role" verification in the route extension takes precedence over the "role" verification in the gateway default - // should fail because we're missing JWT - logger.Log(t, "trying calls to api gateway /pet should fail without JWT token") - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, targetHTTPAddressPet) - - // should fail because we use the token with the wrong role and correct issuer - logger.Log(t, "trying calls to api gateway /pet should fail with wrong role") - k8s.CheckStaticServerHTTPConnectionFailing(t, k8sOptions, StaticClientName, "-H", doctorToken, targetHTTPAddressPet) - - // will succeed because we use the token with the correct role and the correct issuer - logger.Log(t, "trying calls to api gateway /pet should succeed with JWT token with correct role") - k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, "-H", petToken, targetHTTPAddressPet) -} - func checkStatusCondition(t require.TestingT, conditions []metav1.Condition, toCheck metav1.Condition) { for _, c := range conditions { if c.Type == toCheck.Type { diff --git a/acceptance/tests/cloud/basic_test.go b/acceptance/tests/cloud/basic_test.go index e17169700a..7858450904 100644 --- a/acceptance/tests/cloud/basic_test.go +++ b/acceptance/tests/cloud/basic_test.go @@ -129,7 +129,7 @@ func TestBasicCloud(t *testing.T) { localPort, 443, logger.TestLogger{}) - defer tunnel.Close() + // Retry creating the port forward since it can fail occasionally. retry.RunWith(&retry.Counter{Wait: 5 * time.Second, Count: 60}, t, func(r *retry.R) { // NOTE: It's okay to pass in `t` to ForwardPortE despite being in a retry @@ -144,13 +144,12 @@ func TestBasicCloud(t *testing.T) { logger.Log(t, "error finding consul token") return } - + tunnel.Close() logger.Log(t, "consul test token :"+consulToken) releaseName := helpers.RandomName() helmValues := map[string]string{ - "global.imagePullPolicy": "IfNotPresent", "global.cloud.enabled": "true", "global.cloud.resourceId.secretName": resourceSecretName, "global.cloud.resourceId.secretKey": resourceSecretKey, @@ -228,59 +227,7 @@ func TestBasicCloud(t *testing.T) { consulCluster.Create(t) logger.Log(t, "creating static-server deployment") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") - t.Log("Finished deployment. Validating expected conditions now") - // Give some time for collector send metrics - time.Sleep(5 * time.Second) - err = validate(tunnel.Endpoint()) - logger.Log(t, fmt.Sprintf("result: %v", err)) - require.NoError(t, err) - -} - -func validate(endpoint string) error { - tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, - } - - client := &http.Client{Transport: tr} - url := fmt.Sprintf("https://%s/validation", endpoint) - req, err := http.NewRequest("GET", url, nil) - if err != nil { - fmt.Println("Error creating request:", err) - return errors.New("error creating validation request") - } - - // Perform the request - resp, err := client.Do(req) - if err != nil { - fmt.Println("Error sending request:", err) - return errors.New("error making validation request") - } - if resp.StatusCode == http.StatusExpectationFailed { - // Read the response body - body, err := io.ReadAll(resp.Body) - if err != nil { - fmt.Println("Error reading response:", err) - return errors.New("error reading body") - } - var message errMsg - err = json.Unmarshal(body, &message) - if err != nil { - fmt.Println("Error parsing response:", err) - return errors.New("error parsing body") - } - - return fmt.Errorf("Failed validation: %s", message) - } else if resp.StatusCode != http.StatusOK { - return errors.New("unexpected status code response from failure") - } - - return nil - -} - -type errMsg struct { - Error string `json:"error"` + // time.Sleep(1 * time.Hour) + // TODO: add in test assertions here } diff --git a/acceptance/tests/cloud/remote_dev_test.go b/acceptance/tests/cloud/remote_dev_test.go deleted file mode 100644 index 457dc4f269..0000000000 --- a/acceptance/tests/cloud/remote_dev_test.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package cloud - -import ( - "crypto/tls" - "encoding/json" - "os" - "testing" - "time" - - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul-k8s/acceptance/framework/consul" - "github.com/hashicorp/consul-k8s/acceptance/framework/environment" - "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" - "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" - "github.com/hashicorp/consul-k8s/acceptance/framework/logger" - - hcpgnm "github.com/hashicorp/hcp-sdk-go/clients/cloud-global-network-manager-service/preview/2022-02-15/client/global_network_manager_service" - "github.com/hashicorp/hcp-sdk-go/clients/cloud-global-network-manager-service/preview/2022-02-15/models" - hcpcfg "github.com/hashicorp/hcp-sdk-go/config" - "github.com/hashicorp/hcp-sdk-go/httpclient" - "github.com/hashicorp/hcp-sdk-go/resource" -) - -type DevTokenResponse struct { - Token string `json:"token"` -} - -type hcp struct { - ResourceID string - ClientID string - ClientSecret string - AuthURL string - APIHostname string - ScadaAddress string -} - -func TestRemoteDevCloud(t *testing.T) { - _, rIDok := os.LookupEnv("HCP_RESOURCE_ID") - _, cIDok := os.LookupEnv("HCP_CLIENT_ID") - _, cSECok := os.LookupEnv("HCP_CLIENT_SECRET") - - if !rIDok || !cIDok || !cSECok { - t.Log("Must set HCP_RESOURCE_ID, HCP_CLIENT_ID and HCP_CLIENT_SECRET") - t.FailNow() - } - - apiHost := os.Getenv("HCP_AUTH_URL") - if apiHost == "" { - apiHost = "https://api.hcp.dev" - } - authURL := os.Getenv("HCP_API_HOST") - if authURL == "" { - authURL = "https://auth.idp.hcp.dev" - } - scadaAddr := os.Getenv("HCP_SCADA_ADDRESS") - if scadaAddr == "" { - scadaAddr = "scada.internal.hcp.dev:7224" - } - - ctx := suite.Environment().DefaultContext(t) - - kubectlOptions := ctx.KubectlOptions(t) - ns := kubectlOptions.Namespace - k8sClient := environment.KubernetesClientFromOptions(t, kubectlOptions) - - var ( - resourceSecretName = "resource-sec-name" - resourceSecretKey = "resource-sec-key" - resourceSecretKeyValue = os.Getenv("HCP_RESOURCE_ID") - - clientIDSecretName = "clientid-sec-name" - clientIDSecretKey = "clientid-sec-key" - clientIDSecretKeyValue = os.Getenv("HCP_CLIENT_ID") - - clientSecretName = "client-sec-name" - clientSecretKey = "client-sec-key" - clientSecretKeyValue = os.Getenv("HCP_CLIENT_SECRET") - - apiHostSecretName = "apihost-sec-name" - apiHostSecretKey = "apihost-sec-key" - apiHostSecretKeyValue = apiHost - - authUrlSecretName = "authurl-sec-name" - authUrlSecretKey = "authurl-sec-key" - authUrlSecretKeyValue = authURL - - scadaAddressSecretName = "scadaaddress-sec-name" - scadaAddressSecretKey = "scadaaddress-sec-key" - scadaAddressSecretKeyValue = scadaAddr - - bootstrapTokenSecretName = "bootstrap-token" - bootstrapTokenSecretKey = "token" - ) - - hcpCfg := hcp{ - ResourceID: resourceSecretKeyValue, - ClientID: clientIDSecretKeyValue, - ClientSecret: clientSecretKeyValue, - AuthURL: authUrlSecretKeyValue, - APIHostname: apiHostSecretKeyValue, - ScadaAddress: scadaAddressSecretKeyValue, - } - - aclToken := hcpCfg.fetchAgentBootstrapConfig(t) - - cfg := suite.Config() - consul.CreateK8sSecret(t, k8sClient, cfg, ns, resourceSecretName, resourceSecretKey, resourceSecretKeyValue) - consul.CreateK8sSecret(t, k8sClient, cfg, ns, clientIDSecretName, clientIDSecretKey, clientIDSecretKeyValue) - consul.CreateK8sSecret(t, k8sClient, cfg, ns, clientSecretName, clientSecretKey, clientSecretKeyValue) - consul.CreateK8sSecret(t, k8sClient, cfg, ns, apiHostSecretName, apiHostSecretKey, apiHostSecretKeyValue) - consul.CreateK8sSecret(t, k8sClient, cfg, ns, authUrlSecretName, authUrlSecretKey, authUrlSecretKeyValue) - consul.CreateK8sSecret(t, k8sClient, cfg, ns, scadaAddressSecretName, scadaAddressSecretKey, scadaAddressSecretKeyValue) - consul.CreateK8sSecret(t, k8sClient, cfg, ns, bootstrapTokenSecretName, bootstrapTokenSecretKey, aclToken) - - releaseName := helpers.RandomName() - - helmValues := map[string]string{ - "global.imagePullPolicy": "IfNotPresent", - "global.cloud.enabled": "true", - "global.cloud.resourceId.secretName": resourceSecretName, - "global.cloud.resourceId.secretKey": resourceSecretKey, - - "global.cloud.clientId.secretName": clientIDSecretName, - "global.cloud.clientId.secretKey": clientIDSecretKey, - - "global.cloud.clientSecret.secretName": clientSecretName, - "global.cloud.clientSecret.secretKey": clientSecretKey, - - "global.cloud.apiHost.secretName": apiHostSecretName, - "global.cloud.apiHost.secretKey": apiHostSecretKey, - - "global.cloud.authUrl.secretName": authUrlSecretName, - "global.cloud.authUrl.secretKey": authUrlSecretKey, - - "global.cloud.scadaAddress.secretName": scadaAddressSecretName, - "global.cloud.scadaAddress.secretKey": scadaAddressSecretKey, - "connectInject.default": "true", - - "global.acls.manageSystemACLs": "true", - "global.acls.bootstrapToken.secretName": bootstrapTokenSecretName, - "global.acls.bootstrapToken.secretKey": bootstrapTokenSecretKey, - - "global.gossipEncryption.autoGenerate": "false", - "global.tls.enabled": "true", - "global.tls.enableAutoEncrypt": "true", - - "telemetryCollector.enabled": "true", - "telemetryCollector.cloud.clientId.secretName": clientIDSecretName, - "telemetryCollector.cloud.clientId.secretKey": clientIDSecretKey, - - "telemetryCollector.cloud.clientSecret.secretName": clientSecretName, - "telemetryCollector.cloud.clientSecret.secretKey": clientSecretKey, - // Either we set the global.trustedCAs (make sure it's idented exactly) or we - // set TLS to insecure - - "telemetryCollector.extraEnvironmentVars.HCP_API_ADDRESS": apiHostSecretKeyValue, - } - - if cfg.ConsulImage != "" { - helmValues["global.image"] = cfg.ConsulImage - } - if cfg.ConsulCollectorImage != "" { - helmValues["telemetryCollector.image"] = cfg.ConsulCollectorImage - } - - consulCluster := consul.NewHelmCluster(t, helmValues, suite.Environment().DefaultContext(t), cfg, releaseName) - consulCluster.Create(t) - - logger.Log(t, "setting acl permissions for collector and services") - aclDir := "../fixtures/bases/cloud/service-intentions" - k8s.KubectlApplyK(t, ctx.KubectlOptions(t), aclDir) - helpers.Cleanup(t, cfg.NoCleanupOnFailure, cfg.NoCleanup, func() { - k8s.KubectlDeleteK(t, ctx.KubectlOptions(t), aclDir) - }) - - logger.Log(t, "creating static-server deployment") - k8s.DeployKustomize(t, ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/bases/static-server") - time.Sleep(1 * time.Hour) - - // TODO: add in test assertions here - -} - -// fetchAgentBootstrapConfig use the resource-id, client-id, and client-secret -// to call to the agent bootstrap config endpoint and parse the response into a -// CloudBootstrapConfig struct. -func (c *hcp) fetchAgentBootstrapConfig(t *testing.T) string { - cfg, err := c.HCPConfig() - require.NoError(t, err) - logger.Log(t, "Fetching Consul cluster configuration from HCP") - httpClientCfg := httpclient.Config{ - HCPConfig: cfg, - } - clientRuntime, err := httpclient.New(httpClientCfg) - require.NoError(t, err) - - hcpgnmClient := hcpgnm.New(clientRuntime, nil) - clusterResource, err := resource.FromString(c.ResourceID) - require.NoError(t, err) - - params := hcpgnm.NewAgentBootstrapConfigParams(). - WithID(clusterResource.ID). - WithLocationOrganizationID(clusterResource.Organization). - WithLocationProjectID(clusterResource.Project) - - resp, err := hcpgnmClient.AgentBootstrapConfig(params, nil) - require.NoError(t, err) - - bootstrapConfig := resp.GetPayload() - logger.Log(t, "HCP configuration successfully fetched.") - - return c.parseBootstrapConfigResponse(t, bootstrapConfig) -} - -// ConsulConfig represents 'cluster.consul_config' in the response -// fetched from the agent bootstrap config endpoint in HCP. -type ConsulConfig struct { - ACL ACL `json:"acl"` -} - -// ACL represents 'cluster.consul_config.acl' in the response -// fetched from the agent bootstrap config endpoint in HCP. -type ACL struct { - Tokens Tokens `json:"tokens"` -} - -// Tokens represents 'cluster.consul_config.acl.tokens' in the -// response fetched from the agent bootstrap config endpoint in HCP. -type Tokens struct { - Agent string `json:"agent"` - InitialManagement string `json:"initial_management"` -} - -// parseBootstrapConfigResponse unmarshals the boostrap parseBootstrapConfigResponse -// and also sets the HCPConfig values to return CloudBootstrapConfig struct. -func (c *hcp) parseBootstrapConfigResponse(t *testing.T, bootstrapRepsonse *models.HashicorpCloudGlobalNetworkManager20220215AgentBootstrapResponse) string { - - var consulConfig ConsulConfig - err := json.Unmarshal([]byte(bootstrapRepsonse.Bootstrap.ConsulConfig), &consulConfig) - require.NoError(t, err) - - return consulConfig.ACL.Tokens.InitialManagement -} - -func (c *hcp) HCPConfig(opts ...hcpcfg.HCPConfigOption) (hcpcfg.HCPConfig, error) { - if c.ClientID != "" && c.ClientSecret != "" { - opts = append(opts, hcpcfg.WithClientCredentials(c.ClientID, c.ClientSecret)) - } - if c.AuthURL != "" { - opts = append(opts, hcpcfg.WithAuth(c.AuthURL, &tls.Config{})) - } - if c.APIHostname != "" { - opts = append(opts, hcpcfg.WithAPI(c.APIHostname, &tls.Config{})) - } - if c.ScadaAddress != "" { - opts = append(opts, hcpcfg.WithSCADA(c.ScadaAddress, &tls.Config{})) - } - opts = append(opts, hcpcfg.FromEnv(), hcpcfg.WithoutBrowserLogin()) - return hcpcfg.NewHCPConfig(opts...) -} diff --git a/acceptance/tests/connect/connect_inject_test.go b/acceptance/tests/connect/connect_inject_test.go index 7c7f17fc0a..ff8b5bf2df 100644 --- a/acceptance/tests/connect/connect_inject_test.go +++ b/acceptance/tests/connect/connect_inject_test.go @@ -152,6 +152,18 @@ func TestConnectInject_CleanupKilledPods(t *testing.T) { } } }) + // Ensure the token is cleaned up + if secure { + retry.Run(t, func(r *retry.R) { + tokens, _, err := consulClient.ACL().TokenList(nil) + require.NoError(r, err) + for _, t := range tokens { + if strings.Contains(t.Description, podName) { + r.Errorf("Found a token that was supposed to be deleted for pod %v", podName) + } + } + }) + } }) } } diff --git a/acceptance/tests/connect/connect_proxy_lifecycle_test.go b/acceptance/tests/connect/connect_proxy_lifecycle_test.go index 39dd0b4ae7..4a5febfa23 100644 --- a/acceptance/tests/connect/connect_proxy_lifecycle_test.go +++ b/acceptance/tests/connect/connect_proxy_lifecycle_test.go @@ -11,10 +11,10 @@ import ( "testing" "time" + "github.com/gruntwork-io/terratest/modules/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/connhelper" "github.com/hashicorp/consul-k8s/acceptance/framework/consul" "github.com/hashicorp/consul-k8s/acceptance/framework/helpers" - "github.com/hashicorp/consul-k8s/acceptance/framework/k8s" "github.com/hashicorp/consul-k8s/acceptance/framework/logger" "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/stretchr/testify/require" @@ -205,3 +205,172 @@ func TestConnectInject_ProxyLifecycleShutdown(t *testing.T) { }) } } + +func TestConnectInject_ProxyLifecycleShutdownJob(t *testing.T) { + cfg := suite.Config() + + if cfg.EnableTransparentProxy { + // TODO t-eckert: Come back and review this with wise counsel. + t.Skip("Skipping test because transparent proxy is enabled") + } + + defaultGracePeriod := 5 + + cases := map[string]int{ + "../fixtures/cases/jobs/job-client-inject": defaultGracePeriod, + "../fixtures/cases/jobs/job-client-inject-grace-period-0s": 0, + "../fixtures/cases/jobs/job-client-inject-grace-period-10s": 10, + } + + // Set up the installation and static-server once. + ctx := suite.Environment().DefaultContext(t) + releaseName := helpers.RandomName() + + connHelper := connhelper.ConnectHelper{ + ClusterKind: consul.Helm, + ReleaseName: releaseName, + Ctx: ctx, + Cfg: cfg, + HelmValues: map[string]string{ + "connectInject.sidecarProxy.lifecycle.defaultShutdownGracePeriodSeconds": strconv.FormatInt(int64(defaultGracePeriod), 10), + "connectInject.sidecarProxy.lifecycle.defaultEnabled": strconv.FormatBool(true), + }, + } + + connHelper.Setup(t) + connHelper.Install(t) + connHelper.DeployServer(t) + + logger.Log(t, "waiting for static-server to be registered with Consul") + retry.RunWith(&retry.Timer{Timeout: 3 * time.Minute, Wait: 5 * time.Second}, t, func(r *retry.R) { + for _, name := range []string{ + "static-server", + "static-server-sidecar-proxy", + } { + logger.Logf(t, "checking for %s service in Consul catalog", name) + instances, _, err := connHelper.ConsulClient.Catalog().Service(name, "", nil) + r.Check(err) + + if len(instances) != 1 { + r.Errorf("expected 1 instance of %s", name) + + } + } + }) + + // Iterate over the Job cases and test connection. + for path, gracePeriod := range cases { + connHelper.DeployJob(t, path) // Default case. + + logger.Log(t, "waiting for job-client to be registered with Consul") + retry.RunWith(&retry.Timer{Timeout: 300 * time.Second, Wait: 5 * time.Second}, t, func(r *retry.R) { + for _, name := range []string{ + "job-client", + "job-client-sidecar-proxy", + } { + logger.Logf(t, "checking for %s service in Consul catalog", name) + instances, _, err := connHelper.ConsulClient.Catalog().Service(name, "", nil) + r.Check(err) + + if len(instances) != 1 { + r.Errorf("expected 1 instance of %s", name) + } + } + }) + + connHelper.TestConnectionSuccess(t, connhelper.JobName) + + // Get job-client pod name + ns := ctx.KubectlOptions(t).Namespace + pods, err := ctx.KubernetesClient(t).CoreV1().Pods(ns).List( + context.Background(), + metav1.ListOptions{ + LabelSelector: "app=job-client", + }, + ) + require.NoError(t, err) + require.Len(t, pods.Items, 1) + jobName := pods.Items[0].Name + + // Exec into job and send shutdown request to running proxy. + // curl --max-time 2 -s -f -XPOST http://127.0.0.1:20600/graceful_shutdown + sendProxyShutdownArgs := []string{"exec", jobName, "-c", connhelper.JobName, "--", "curl", "--max-time", "2", "-s", "-f", "-XPOST", "http://127.0.0.1:20600/graceful_shutdown"} + _, err = k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), sendProxyShutdownArgs...) + require.NoError(t, err) + + logger.Log(t, "Proxy killed...") + + args := []string{"exec", jobName, "-c", connhelper.JobName, "--", "curl", "-vvvsSf"} + if cfg.EnableTransparentProxy { + args = append(args, "http://static-server") + } else { + args = append(args, "http://localhost:1234") + } + + if gracePeriod > 0 { + logger.Log(t, "Checking if connection successful within grace period...") + retry.RunWith(&retry.Timer{Timeout: time.Duration(gracePeriod) * time.Second, Wait: 2 * time.Second}, t, func(r *retry.R) { + output, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), args...) + require.NoError(r, err) + require.True(r, !strings.Contains(output, "curl: (7) Failed to connect")) + }) + //wait for the grace period to end after successful request + time.Sleep(time.Duration(gracePeriod) * time.Second) + } + + // Test that requests fail once grace period has ended, or there was no grace period set. + logger.Log(t, "Checking that requests fail now that proxy is killed...") + retry.RunWith(&retry.Timer{Timeout: 2 * time.Minute, Wait: 2 * time.Second}, t, func(r *retry.R) { + output, err := k8s.RunKubectlAndGetOutputE(t, ctx.KubectlOptions(t), args...) + require.Error(r, err) + require.True(r, strings.Contains(output, "curl: (7) Failed to connect")) + }) + + // Wait for the job to complete. + retry.RunWith(&retry.Timer{Timeout: 4 * time.Minute, Wait: 30 * time.Second}, t, func(r *retry.R) { + logger.Log(t, "Checking if job completed...") + jobs, err := ctx.KubernetesClient(t).BatchV1().Jobs(ns).List( + context.Background(), + metav1.ListOptions{ + LabelSelector: "app=job-client", + }, + ) + require.NoError(r, err) + require.True(r, jobs.Items[0].Status.Succeeded == 1) + }) + + // Delete the job and its associated Pod. + pods, err = ctx.KubernetesClient(t).CoreV1().Pods(ns).List( + context.Background(), + metav1.ListOptions{ + LabelSelector: "app=job-client", + }, + ) + require.NoError(t, err) + podName := pods.Items[0].Name + + err = ctx.KubernetesClient(t).BatchV1().Jobs(ns).Delete(context.Background(), "job-client", metav1.DeleteOptions{}) + require.NoError(t, err) + + err = ctx.KubernetesClient(t).CoreV1().Pods(ns).Delete(context.Background(), podName, metav1.DeleteOptions{}) + require.NoError(t, err) + + logger.Log(t, "ensuring job is deregistered after termination") + retry.RunWith(&retry.Timer{Timeout: 4 * time.Minute, Wait: 30 * time.Second}, t, func(r *retry.R) { + for _, name := range []string{ + "job-client", + "job-client-sidecar-proxy", + } { + logger.Logf(t, "checking for %s service in Consul catalog", name) + instances, _, err := connHelper.ConsulClient.Catalog().Service(name, "", nil) + r.Check(err) + + for _, instance := range instances { + if strings.Contains(instance.ServiceID, jobName) { + r.Errorf("%s is still registered", instance.ServiceID) + } + } + } + }) + } +} diff --git a/acceptance/tests/connect/permissive_mtls_test.go b/acceptance/tests/connect/permissive_mtls_test.go index 929d56acfd..52b5ba513e 100644 --- a/acceptance/tests/connect/permissive_mtls_test.go +++ b/acceptance/tests/connect/permissive_mtls_test.go @@ -67,7 +67,7 @@ func deployStaticServer(t *testing.T, cfg *config.TestConfig, ch connhelper.Conn t.Helper() logger.Log(t, "Creating static-server deployment with connect-inject=true") - k8s.DeployKustomize(t, ch.Ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") + k8s.DeployKustomize(t, ch.Ctx.KubectlOptions(t), cfg.NoCleanupOnFailure, ch.Cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") requirePodContainers(t, ch, "app=static-server", 2) } diff --git a/acceptance/tests/fixtures/bases/cloud/service-intentions/acl.yaml b/acceptance/tests/fixtures/bases/cloud/service-intentions/acl.yaml deleted file mode 100644 index fb3f77f496..0000000000 --- a/acceptance/tests/fixtures/bases/cloud/service-intentions/acl.yaml +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ServiceIntentions -metadata: - name: consul-telemetry-collector -spec: - destination: - name: 'consul-telemetry-collector' - sources: - - name: '*' - action: allow - - - \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/job-client/job.yaml b/acceptance/tests/fixtures/bases/job-client/job.yaml new file mode 100644 index 0000000000..cc5f2f2896 --- /dev/null +++ b/acceptance/tests/fixtures/bases/job-client/job.yaml @@ -0,0 +1,27 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: job-client + namespace: default + labels: + app: job-client +spec: + template: + metadata: + labels: + app: job-client + spec: + containers: + - name: job-client + image: alpine/curl:3.14 + ports: + - containerPort: 80 + command: + - /bin/sh + - -c + - | + echo "Started test job" + sleep 120 + echo "Ended test job" + serviceAccountName: job-client + restartPolicy: Never diff --git a/acceptance/tests/fixtures/bases/cloud/service-intentions/kustomization.yaml b/acceptance/tests/fixtures/bases/job-client/kustomization.yaml similarity index 58% rename from acceptance/tests/fixtures/bases/cloud/service-intentions/kustomization.yaml rename to acceptance/tests/fixtures/bases/job-client/kustomization.yaml index 9c19bf4ca3..390d19c859 100644 --- a/acceptance/tests/fixtures/bases/cloud/service-intentions/kustomization.yaml +++ b/acceptance/tests/fixtures/bases/job-client/kustomization.yaml @@ -2,4 +2,6 @@ # SPDX-License-Identifier: MPL-2.0 resources: - - acl.yaml \ No newline at end of file + - ./job.yaml + - service.yaml + - serviceaccount.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/job-client/service.yaml b/acceptance/tests/fixtures/bases/job-client/service.yaml new file mode 100644 index 0000000000..36ec16133a --- /dev/null +++ b/acceptance/tests/fixtures/bases/job-client/service.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Service +metadata: + name: job-client + namespace: default +spec: + selector: + app: job-client + ports: + - port: 80 \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/job-client/serviceaccount.yaml b/acceptance/tests/fixtures/bases/job-client/serviceaccount.yaml new file mode 100644 index 0000000000..b4637d4d55 --- /dev/null +++ b/acceptance/tests/fixtures/bases/job-client/serviceaccount.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: job-client + namespace: default \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml b/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml index 87f6a71f32..f88d143728 100644 --- a/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml +++ b/acceptance/tests/fixtures/bases/sameness/override-ns/service-defaults.yaml @@ -1,6 +1,3 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - apiVersion: consul.hashicorp.com/v1alpha1 kind: ServiceDefaults metadata: diff --git a/acceptance/tests/fixtures/bases/sameness/peering/mesh/mesh.yaml b/acceptance/tests/fixtures/bases/sameness/peering/mesh/mesh.yaml index 2fb6a04bb6..de84382d3e 100644 --- a/acceptance/tests/fixtures/bases/sameness/peering/mesh/mesh.yaml +++ b/acceptance/tests/fixtures/bases/sameness/peering/mesh/mesh.yaml @@ -1,6 +1,3 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - apiVersion: consul.hashicorp.com/v1alpha1 kind: Mesh metadata: diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/api-gateway.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/api-gateway.yaml deleted file mode 100644 index bef7e96f12..0000000000 --- a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/api-gateway.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: gateway.networking.k8s.io/v1beta1 -kind: Gateway -metadata: - name: gateway -spec: - gatewayClassName: gateway-class - listeners: - - protocol: HTTP - port: 8080 - name: http-auth - allowedRoutes: - namespaces: - from: "All" - - protocol: HTTP - port: 80 - name: http - allowedRoutes: - namespaces: - from: "All" - - protocol: TCP - port: 81 - name: tcp - allowedRoutes: - namespaces: - from: "All" - - protocol: HTTPS - port: 443 - name: https - tls: - certificateRefs: - - name: "certificate" - allowedRoutes: - namespaces: - from: "All" diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/gateway-policy.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/gateway-policy.yaml deleted file mode 100644 index 8e47d75062..0000000000 --- a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/gateway-policy.yaml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: ConsulGatewayPolicy -metadata: - name: my-policy -spec: - targetRef: - name: gateway - kind: Gateway - group: gateway.networking.kuberenetes.io - sectionName: http - override: - Providers: - - Provider: "local" - VerifyClaims: - - Path: - - "iss" - Value: "local" - default: - Providers: - - Provider: "local" - VerifyClaims: - - Path: - - "iss" - Value: "local" diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute-auth.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute-auth.yaml deleted file mode 100644 index 4963277c55..0000000000 --- a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute-auth.yaml +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: gateway.networking.k8s.io/v1beta1 -kind: HTTPRoute -metadata: - name: http-route-auth -spec: - parentRefs: - - name: gateway - sectionName: http-auth - rules: - - matches: - - path: - type: PathPrefix - value: "/admin" - backendRefs: - - name: static-server - port: 80 - filters: - - type: ExtensionRef - extensionRef: - group: consul.hashicorp.com - kind: HTTPRouteAuthFilter - name: route-jwt-auth-filter - - matches: - - path: - type: PathPrefix - value: "/pet" - backendRefs: - - name: static-server - port: 80 diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute.yaml deleted file mode 100644 index 52e206a91e..0000000000 --- a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/httproute.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: gateway.networking.k8s.io/v1beta1 -kind: HTTPRoute -metadata: - name: http-route -spec: - parentRefs: - - name: gateway - sectionName: http - rules: - - matches: - - path: - type: PathPrefix - value: "/v1" - backendRefs: - - name: static-server - port: 80 diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-provider.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-provider.yaml deleted file mode 100644 index 37eb034d3c..0000000000 --- a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-provider.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: JWTProvider -metadata: - name: local -spec: - issuer: local - jsonWebKeySet: - local: - jwks: "ewogICAgImtleXMiOiBbCiAgICAgICAgewogICAgICAgICAgICAicCI6ICI5TTlWSVhJR0hpR3FlTnhseEJ2V0xFV09oUFh3dXhXZUpod01uM3dGdG9STEtfZmF6VWxjWEc1cUViLTdpMXo3VmlPUWVZRnh6WUZYTS1pbVU3OVFRa1dTVUVSazR2dHZuc2R5UnpUSnVPc3A0ZUhuWFVMSHJPOU51NkJ5bC1VeVprMzFvSnFGeGllM0pHQXlRLUM2OVF2NVFkVjFZV0hfVDkyTzk4d1hYZGMiLAogICAgICAgICAgICAia3R5IjogIlJTQSIsCiAgICAgICAgICAgICJxIjogInFIVnZBb3h0ckgxUTVza25veXNMMkhvbC1ubnU3ZlM3Mjg4clRGdE9jeG9Jb29nWXBKVTljemxwcjctSlo2bjc0TUViVHBBMHRkSUR5TEtQQ0xIN3JKTFRrZzBDZVZNQWpmY01zdkRUcWdFOHNBWE42bzd2ZjYya2hwcExYOHVCU3JxSHkyV1JhZXJsbDROU09hcmRGSkQ2MWhHSVF2cEpXRk4xazFTV3pWcyIsCiAgICAgICAgICAgICJkIjogIlp3elJsVklRZkg5ekZ6d1hOZ2hEMHhkZVctalBCbmRkWnJNZ0wwQ2JjeXZZYlg2X1c0ajlhM1dmYWpobmI2bTFILW9CWjRMczVmNXNRVTB2ZFJ2ZG1laFItUG43aWNRcUdURFNKUTYtdWVtNm15UVRWaEo2UmZiM0lINVJ2VDJTOXUzcVFDZWFadWN3aXFoZ1RCbFhnOWFfV0pwVHJYNFhPQ3JCR1ZsTng3Z2JETVJOamNEN0FnRkZ3S2p2TEZVdDRLTkZmdEJqaFF0TDFLQ2VwblNmamtvRm1RUTVlX3RSS2ozX2U1V3pNSkJkekpQejNkR2YxZEk3OF9wYmJFbmFMcWhqNWg0WUx2UU5JUUhVcURYSGx4ZDc1Qlh3aFJReE1nUDRfd1EwTFk2cVRKNGFDa2Q0RDJBTUtqMzJqeVFiVTRKTE9jQjFNMnZBRWFyc2NTU3l0USIsCiAgICAgICAgICAgICJlIjogIkFRQUIiLAogICAgICAgICAgICAidXNlIjogInNpZyIsCiAgICAgICAgICAgICJraWQiOiAiQy1FMW5DandnQkMtUHVHTTJPNDY3RlJEaEt4OEFrVmN0SVNBYm8zcmlldyIsCiAgICAgICAgICAgICJxaSI6ICJ0N2VOQjhQV21xVHdKREZLQlZKZExrZnJJT2drMFJ4MnREODBGNHB5cjhmNzRuNGlVWXFmWG1haVZtbGx2c2FlT3JlNHlIczQ4UE45NVZsZlVvS3Z6ZEJFaDNZTDFINGZTOGlYYXNzNGJiVnVuWHR4U0hMZFFPYUNZYUplSmhBbGMyUWQ4elR0NFFQWk9yRWVWLVJTYU0tN095ekkwUWtSSF9tcmk1YmRrOXMiLAogICAgICAgICAgICAiZHAiOiAiYnBLckQtVXhrRENDal81MFZLU0NFeE1Ec1Zob2VBZm1tNjMxb1o5aDhUTkZ4TUU1YVptbUJ2VzBJUG9wMm1PUF9qTW9FVWxfUG1RYUlBOEgtVEdqTFp2QTMxSlZBeFN3TU5aQzdwaVFPRjYzVnhneTZUTzlmb1hENVdndC1oLUNxU1N6T2V3eFdmUWNTMmpMcTA3NUFxOTYwTnA2SHhjbE8weUdRN1JDSlpjIiwKICAgICAgICAgICAgImFsZyI6ICJQUzI1NiIsCiAgICAgICAgICAgICJkcSI6ICJpdVZveGwwckFKSEM1c2JzbTZpZWQ3c2ZIVXIwS2Rja0hiVFBLb0lPU1BFcU5YaXBlT3BrWkdEdU55NWlDTXNyRnNHaDFrRW9kTkhZdE40ay1USm5KSDliV296SGdXbGloNnN2R1V0Zi1raFMxWC16ckxaMTJudzlyNDRBbjllWG54bjFaVXMxZm5OakltM3dtZ083algyTWxIeVlNVUZVd0RMd09xNEFPUWsiLAogICAgICAgICAgICAibiI6ICJvUmhjeUREdmp3NFZ4SHRRNTZhRDlNSmRTaWhWSk1nTHd1b2FCQVhhc0RjVDNEWVZjcENlVGxDMVBPdzdPNW1Ec2ZSWVFtcGpoendyRDVZWU8yeDE4REl4czdyNTNJdFMxRy1ybnQxQ1diVE9fUzFJT01DR2xxYzh5VWJnLUhSUkRETXQyb2V3TjJoRGtxYlBKVFJNbXpjRkpNMHRpTm1RZVVMcWViZEVYaWVUblJMT1BkMWg2ZmJycVNLS01mSXlIbGZ1WXFQc1VWSEdkMVBESGljZ3NMazFtZDhtYTNIS1hWM0hJdzZrdUV6R0hQb1gxNHo4YWF6RFFZWndUR3ZxVGlPLUdRUlVDZUJueVo4bVhyWnRmSjNqVk83UUhXcEx3MlM1VDVwVTRwcE0xQXppWTFxUDVfY3ZpOTNZT2Zrb09PalRTX3V3RENZWGFxWjB5bTJHYlEiCiAgICAgICAgfQogICAgXQp9Cg==" diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-route-filter.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-route-filter.yaml deleted file mode 100644 index e0a3128bed..0000000000 --- a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/jwt-route-filter.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: consul.hashicorp.com/v1alpha1 -kind: HTTPRouteAuthFilter -metadata: - name: example-route-jwt-filter -spec: - type: JWT - JWTProviders: - - Provider: "local" - VerifyClaims: - - Path: - - "role" - Value: "doctor" diff --git a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/kustomization.yaml b/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/kustomization.yaml deleted file mode 100644 index 3dc38a090c..0000000000 --- a/acceptance/tests/fixtures/cases/api-gateways/jwt-auth/kustomization.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -resources: - - ../../../bases/api-gateway - - ../../static-server-inject - - ./httproute.yaml - - ./jwt-provider.yaml - -patchesStrategicMerge: - - httproute-no-auth.yaml - - api-gateway.yaml diff --git a/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-0s/kustomization.yaml b/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-0s/kustomization.yaml new file mode 100644 index 0000000000..d87dbf0481 --- /dev/null +++ b/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-0s/kustomization.yaml @@ -0,0 +1,6 @@ + +resources: + - ../../../bases/job-client + +patchesStrategicMerge: + - patch.yaml diff --git a/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-0s/patch.yaml b/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-0s/patch.yaml new file mode 100644 index 0000000000..46d1a417ea --- /dev/null +++ b/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-0s/patch.yaml @@ -0,0 +1,12 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: job-client +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + "consul.hashicorp.com/transparent-proxy": "false" + "consul.hashicorp.com/connect-service-upstreams": "static-server:1234" + "consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds": "0" \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-10s/kustomization.yaml b/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-10s/kustomization.yaml new file mode 100644 index 0000000000..d87dbf0481 --- /dev/null +++ b/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-10s/kustomization.yaml @@ -0,0 +1,6 @@ + +resources: + - ../../../bases/job-client + +patchesStrategicMerge: + - patch.yaml diff --git a/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-10s/patch.yaml b/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-10s/patch.yaml new file mode 100644 index 0000000000..4db2df127e --- /dev/null +++ b/acceptance/tests/fixtures/cases/jobs/job-client-inject-grace-period-10s/patch.yaml @@ -0,0 +1,12 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: job-client +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + "consul.hashicorp.com/transparent-proxy": "false" + "consul.hashicorp.com/connect-service-upstreams": "static-server:1234" + "consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds": "10" \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/jobs/job-client-inject/kustomization.yaml b/acceptance/tests/fixtures/cases/jobs/job-client-inject/kustomization.yaml new file mode 100644 index 0000000000..0aee0558b7 --- /dev/null +++ b/acceptance/tests/fixtures/cases/jobs/job-client-inject/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../bases/job-client + +patchesStrategicMerge: + - patch.yaml diff --git a/acceptance/tests/fixtures/cases/jobs/job-client-inject/patch.yaml b/acceptance/tests/fixtures/cases/jobs/job-client-inject/patch.yaml new file mode 100644 index 0000000000..5f390c1f7e --- /dev/null +++ b/acceptance/tests/fixtures/cases/jobs/job-client-inject/patch.yaml @@ -0,0 +1,12 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: job-client +spec: + template: + metadata: + annotations: + "consul.hashicorp.com/connect-inject": "true" + "consul.hashicorp.com/transparent-proxy": "false" + "consul.hashicorp.com/sidecar-proxy-lifecycle-shutdown-grace-period-seconds": "5" + "consul.hashicorp.com/connect-service-upstreams": "static-server:1234" \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition-tproxy/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition-tproxy/kustomization.yaml new file mode 100644 index 0000000000..227f223c9f --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition-tproxy/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/static-client + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition-tproxy/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition-tproxy/patch.yaml new file mode 100644 index 0000000000..68f3c8dd91 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-client/ap1-partition-tproxy/patch.yaml @@ -0,0 +1,21 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-client +spec: + template: + metadata: + annotations: + 'consul.hashicorp.com/connect-inject': 'true' + spec: + containers: + - name: static-client + image: anubhavmishra/tiny-tools:latest + # Just spin & wait forever, we'll use `kubectl exec` to demo + command: ['/bin/sh', '-c', '--'] + args: ['while true; do sleep 30; done;'] + # If ACLs are enabled, the serviceAccountName must match the Consul service name. + serviceAccountName: static-client diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/default-partition-tproxy/kustomization.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/default-partition-tproxy/kustomization.yaml new file mode 100644 index 0000000000..227f223c9f --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-client/default-partition-tproxy/kustomization.yaml @@ -0,0 +1,8 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +resources: + - ../../../../bases/static-client + +patchesStrategicMerge: + - patch.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/cases/sameness/static-client/default-partition-tproxy/patch.yaml b/acceptance/tests/fixtures/cases/sameness/static-client/default-partition-tproxy/patch.yaml new file mode 100644 index 0000000000..e53ef7b509 --- /dev/null +++ b/acceptance/tests/fixtures/cases/sameness/static-client/default-partition-tproxy/patch.yaml @@ -0,0 +1,21 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: static-client +spec: + template: + metadata: + annotations: + 'consul.hashicorp.com/connect-inject': 'true' + spec: + containers: + - name: static-client + image: anubhavmishra/tiny-tools:latest + # Just spin & wait forever, we'll use `kubectl exec` to demo + command: ['/bin/sh', '-c', '--'] + args: ['while true; do sleep 30; done;'] + # If ACLs are enabled, the serviceAccountName must match the Consul service name. + serviceAccountName: static-client \ No newline at end of file diff --git a/acceptance/tests/sameness/sameness_test.go b/acceptance/tests/sameness/sameness_test.go index 629b886d95..baf967b24d 100644 --- a/acceptance/tests/sameness/sameness_test.go +++ b/acceptance/tests/sameness/sameness_test.go @@ -1,6 +1,3 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - package sameness import ( @@ -428,21 +425,30 @@ func TestFailover_Connect(t *testing.T) { "../fixtures/cases/sameness/static-server/dc3") // Create static client deployments. + staticClientKustomizeDirDefault := "../fixtures/cases/sameness/static-client/default-partition" + staticClientKustomizeDirAP1 := "../fixtures/cases/sameness/static-client/ap1-partition" + + // If transparent proxy is enabled create clients without explicit upstreams + if cfg.EnableTransparentProxy { + staticClientKustomizeDirDefault = fmt.Sprintf("%s-%s", staticClientKustomizeDirDefault, "tproxy") + staticClientKustomizeDirAP1 = fmt.Sprintf("%s-%s", staticClientKustomizeDirAP1, "tproxy") + } + k8s.DeployKustomize(t, testClusters[keyCluster01a].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, - "../fixtures/cases/sameness/static-client/default-partition") + staticClientKustomizeDirDefault) k8s.DeployKustomize(t, testClusters[keyCluster02a].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, - "../fixtures/cases/sameness/static-client/default-partition") + staticClientKustomizeDirDefault) k8s.DeployKustomize(t, testClusters[keyCluster03a].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, - "../fixtures/cases/sameness/static-client/default-partition") + staticClientKustomizeDirDefault) k8s.DeployKustomize(t, testClusters[keyCluster01b].clientOpts, cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, - "../fixtures/cases/sameness/static-client/ap1-partition") + staticClientKustomizeDirAP1) // Verify that both static-server and static-client have been injected and now have 2 containers in each cluster. // Also get the server IP testClusters.setServerIP(t) // Everything should be up and running now - testClusters.verifyServerUpState(t) + testClusters.verifyServerUpState(t, cfg.EnableTransparentProxy) logger.Log(t, "all infrastructure up and running") // Verify all the failover Scenarios @@ -514,19 +520,23 @@ func TestFailover_Connect(t *testing.T) { checkDNSPQ: true, }, } - for _, sc := range subCases { t.Run(sc.name, func(t *testing.T) { // Reset the scale of all servers testClusters.resetScale(t) - testClusters.verifyServerUpState(t) + testClusters.verifyServerUpState(t, cfg.EnableTransparentProxy) // We're resetting the scale, so make sure we have all the new IP addresses saved testClusters.setServerIP(t) for _, v := range sc.failovers { // Verify Failover (If this is the first check, then just verifying we're starting with the right server) logger.Log(t, "checking service failover") - serviceFailoverCheck(t, sc.server, v.failoverServer.name) + + if cfg.EnableTransparentProxy { + serviceFailoverCheck(t, sc.server, v.failoverServer.name, fmt.Sprintf("http://static-server.virtual.ns2.ns.%s.ap.consul", sc.server.fullTextPartition())) + } else { + serviceFailoverCheck(t, sc.server, v.failoverServer.name, "localhost:8080") + } // Verify DNS if sc.checkDNSPQ { @@ -578,6 +588,14 @@ type cluster struct { acceptors []string } +func (c cluster) fullTextPartition() string { + if c.partition == "" { + return "default" + } else { + return c.partition + } +} + type clusters map[string]*cluster func (c clusters) resetScale(t *testing.T) { @@ -609,11 +627,15 @@ func (c clusters) setServerIP(t *testing.T) { // verifyServerUpState will verify that the static-servers are all up and running as // expected by curling them from their local datacenters. -func (c clusters) verifyServerUpState(t *testing.T) { +func (c clusters) verifyServerUpState(t *testing.T, isTproxyEnabled bool) { logger.Logf(t, "verifying that static-servers are up") for _, v := range c { // Query using a client and expect its own name, no failover should occur - serviceFailoverCheck(t, v, v.name) + if isTproxyEnabled { + serviceFailoverCheck(t, v, v.name, fmt.Sprintf("http://static-server.virtual.ns2.ns.%s.ap.consul", v.fullTextPartition())) + } else { + serviceFailoverCheck(t, v, v.name, "localhost:8080") + } } } @@ -643,13 +665,13 @@ func applyResources(t *testing.T, cfg *config.TestConfig, kustomizeDir string, o // serviceFailoverCheck verifies that the server failed over as expected by checking that curling the `static-server` // using the `static-client` responds with the expected cluster name. Each static-server responds with a uniquue // name so that we can verify failover occured as expected. -func serviceFailoverCheck(t *testing.T, server *cluster, expectedName string) { +func serviceFailoverCheck(t *testing.T, server *cluster, expectedName string, curlAddress string) { timer := &retry.Timer{Timeout: retryTimeout, Wait: 5 * time.Second} var resp string var err error retry.RunWith(timer, t, func(r *retry.R) { resp, err = k8s.RunKubectlAndGetOutputE(t, server.clientOpts, "exec", "-i", - staticClientDeployment, "-c", staticClientName, "--", "curl", "localhost:8080") + staticClientDeployment, "-c", staticClientName, "--", "curl", curlAddress) require.NoError(r, err) assert.Contains(r, resp, expectedName) }) diff --git a/acceptance/tests/vault/vault_wan_fed_test.go b/acceptance/tests/vault/vault_wan_fed_test.go index fa63c4d5fb..a2a18842b5 100644 --- a/acceptance/tests/vault/vault_wan_fed_test.go +++ b/acceptance/tests/vault/vault_wan_fed_test.go @@ -31,7 +31,6 @@ import ( // in the secondary that will treat the Vault server in the primary as an external server. func TestVault_WANFederationViaGateways(t *testing.T) { cfg := suite.Config() - if cfg.UseKind { t.Skipf("Skipping this test because it's currently flaky on kind") } @@ -498,7 +497,6 @@ func TestVault_WANFederationViaGateways(t *testing.T) { }) // Check that we can connect services over the mesh gateways. - logger.Log(t, "creating static-server in dc2") k8s.DeployKustomize(t, secondaryCtx.KubectlOptions(t), cfg.NoCleanupOnFailure, cfg.NoCleanup, cfg.DebugDirectory, "../fixtures/cases/static-server-inject") @@ -520,7 +518,6 @@ func TestVault_WANFederationViaGateways(t *testing.T) { logger.Log(t, "checking that connection is successful") k8s.CheckStaticServerConnectionSuccessful(t, primaryCtx.KubectlOptions(t), StaticClientName, "http://localhost:1234") - } // vaultAddress returns Vault's server URL depending on test configuration. diff --git a/charts/consul/Chart.yaml b/charts/consul/Chart.yaml index de8e6e9df6..ae810c87d5 100644 --- a/charts/consul/Chart.yaml +++ b/charts/consul/Chart.yaml @@ -3,8 +3,8 @@ apiVersion: v2 name: consul -version: 1.3.0-dev -appVersion: 1.17-dev +version: 1.2.2-dev +appVersion: 1.16-dev kubeVersion: ">=1.22.0-0" description: Official HashiCorp Consul Chart home: https://www.consul.io @@ -16,13 +16,13 @@ annotations: artifacthub.io/prerelease: true artifacthub.io/images: | - name: consul - image: docker.mirror.hashicorp.services/hashicorppreview/consul-enterprise:1.17-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul:1.16-dev - name: consul-k8s-control-plane - image: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.3.0-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.2.2-dev - name: consul-dataplane - image: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.3-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.2-dev - name: envoy - image: envoyproxy/envoy:v1.26.2 + image: envoyproxy/envoy:v1.25.9 artifacthub.io/license: MPL-2.0 artifacthub.io/links: | - name: Documentation diff --git a/charts/consul/templates/_helpers.tpl b/charts/consul/templates/_helpers.tpl index 18f57b188c..30aca54b1e 100644 --- a/charts/consul/templates/_helpers.tpl +++ b/charts/consul/templates/_helpers.tpl @@ -19,9 +19,12 @@ as well as the global.name setting. {{- if not .Values.global.enablePodSecurityPolicies -}} securityContext: allowPrivilegeEscalation: false + readOnlyRootFilesystem: true capabilities: drop: - ALL + add: + - NET_BIND_SERVICE runAsNonRoot: true seccompProfile: type: RuntimeDefault diff --git a/charts/consul/templates/crd-gatewayclasses.yaml b/charts/consul/templates/crd-gatewayclasses.yaml index b0725c2baf..f7b039531f 100644 --- a/charts/consul/templates/crd-gatewayclasses.yaml +++ b/charts/consul/templates/crd-gatewayclasses.yaml @@ -1,7 +1,6 @@ {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-gateways.yaml b/charts/consul/templates/crd-gateways.yaml index 923a75477d..ae5de48de9 100644 --- a/charts/consul/templates/crd-gateways.yaml +++ b/charts/consul/templates/crd-gateways.yaml @@ -1,7 +1,6 @@ {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-grpcroutes.yaml b/charts/consul/templates/crd-grpcroutes.yaml index 07412ba60b..8f22dbc196 100644 --- a/charts/consul/templates/crd-grpcroutes.yaml +++ b/charts/consul/templates/crd-grpcroutes.yaml @@ -1,7 +1,6 @@ {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-httproutes.yaml b/charts/consul/templates/crd-httproutes.yaml index d9055e7406..2aa4478c66 100644 --- a/charts/consul/templates/crd-httproutes.yaml +++ b/charts/consul/templates/crd-httproutes.yaml @@ -1,7 +1,6 @@ {{- if and .Values.connectInject.enabled .Values.connectInject.apiGateway.manageExternalCRDs }} # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 - apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: diff --git a/charts/consul/templates/crd-referencegrants.yaml b/charts/consul/templates/crd-referencegrants.yaml index 6ae177d987..d50211291d 100644 --- a/charts/consul/templates/crd-referencegrants.yaml +++ b/charts/consul/templates/crd-referencegrants.yaml @@ -7,15 +7,15 @@ kind: CustomResourceDefinition metadata: annotations: api-approved.kubernetes.io: https://github.com/kubernetes-sigs/gateway-api/pull/1538 + gateway.networking.k8s.io/bundle-version: v0.6.2 + gateway.networking.k8s.io/channel: experimental + creationTimestamp: null labels: app: {{ template "consul.name" . }} chart: {{ template "consul.chart" . }} heritage: {{ .Release.Service }} release: {{ .Release.Name }} component: crd - gateway.networking.k8s.io/bundle-version: v0.6.2 - gateway.networking.k8s.io/channel: experimental - creationTimestamp: null name: referencegrants.gateway.networking.k8s.io spec: group: gateway.networking.k8s.io diff --git a/charts/consul/templates/crd-serviceresolvers.yaml b/charts/consul/templates/crd-serviceresolvers.yaml index eb5643fe49..0d46f83539 100644 --- a/charts/consul/templates/crd-serviceresolvers.yaml +++ b/charts/consul/templates/crd-serviceresolvers.yaml @@ -227,16 +227,6 @@ spec: type: integer type: object type: object - prioritizeByLocality: - description: PrioritizeByLocality controls whether the locality of - services within the local partition will be used to prioritize connectivity. - properties: - mode: - description: 'Mode specifies the type of prioritization that will - be performed when selecting nodes in the local partition. Valid - values are: "" (default "none"), "none", and "failover".' - type: string - type: object redirect: description: Redirect when configured, all attempts to resolve the service this resolver defines will be substituted for the supplied diff --git a/charts/consul/templates/ingress-gateways-deployment.yaml b/charts/consul/templates/ingress-gateways-deployment.yaml index c10f1549f6..d755a80e39 100644 --- a/charts/consul/templates/ingress-gateways-deployment.yaml +++ b/charts/consul/templates/ingress-gateways-deployment.yaml @@ -154,6 +154,9 @@ spec: terminationGracePeriodSeconds: {{ default $defaults.terminationGracePeriodSeconds .terminationGracePeriodSeconds }} serviceAccountName: {{ template "consul.fullname" $root }}-{{ .name }} volumes: + - name: tmp + emptyDir: + medium: "Memory" - name: consul-service emptyDir: medium: "Memory" @@ -215,6 +218,8 @@ spec: -log-level={{ default $root.Values.global.logLevel $root.Values.ingressGateways.logLevel }} \ -log-json={{ $root.Values.global.logJSON }} volumeMounts: + - name: tmp + mountPath: /tmp - name: consul-service mountPath: /consul/service {{- if $root.Values.global.tls.enabled }} @@ -239,6 +244,8 @@ spec: resources: {{ toYaml (default $defaults.resources .resources) | nindent 10 }} {{- end }} volumeMounts: + - name: tmp + mountPath: /tmp - name: consul-service mountPath: /consul/service readOnly: true diff --git a/charts/consul/templates/server-statefulset.yaml b/charts/consul/templates/server-statefulset.yaml index 74613b19ff..c40848fc9b 100644 --- a/charts/consul/templates/server-statefulset.yaml +++ b/charts/consul/templates/server-statefulset.yaml @@ -147,6 +147,8 @@ spec: {{- toYaml .Values.server.securityContext | nindent 8 }} {{- end }} volumes: + - name: tmp + emptyDir: {} - name: config configMap: name: {{ template "consul.fullname" . }}-server-config @@ -248,7 +250,6 @@ spec: containers: - name: consul image: "{{ default .Values.global.image .Values.server.image }}" - imagePullPolicy: {{ .Values.global.imagePullPolicy }} env: - name: ADVERTISE_IP valueFrom: @@ -456,6 +457,9 @@ spec: mountPath: /trusted-cas readOnly: false {{- end }} + - name: tmp + mountPath: /tmp + readOnly: false ports: {{- if (or (not .Values.global.tls.enabled) (not .Values.global.tls.httpsOnly)) }} - name: http diff --git a/charts/consul/templates/telemetry-collector-deployment.yaml b/charts/consul/templates/telemetry-collector-deployment.yaml index 4b5bb6df7b..bf00fd9a03 100644 --- a/charts/consul/templates/telemetry-collector-deployment.yaml +++ b/charts/consul/templates/telemetry-collector-deployment.yaml @@ -150,7 +150,7 @@ spec: containers: - name: consul-telemetry-collector image: {{ .Values.telemetryCollector.image }} - imagePullPolicy: {{ .Values.global.imagePullPolicy }} + imagePullPolicy: Always ports: - containerPort: 9090 name: metrics diff --git a/charts/consul/templates/terminating-gateways-deployment.yaml b/charts/consul/templates/terminating-gateways-deployment.yaml index 9433e44bc9..ccfcf3c6a6 100644 --- a/charts/consul/templates/terminating-gateways-deployment.yaml +++ b/charts/consul/templates/terminating-gateways-deployment.yaml @@ -123,6 +123,9 @@ spec: terminationGracePeriodSeconds: 10 serviceAccountName: {{ template "consul.fullname" $root }}-{{ .name }} volumes: + - name: tmp + emptyDir: + medium: "Memory" - name: consul-service emptyDir: medium: "Memory" @@ -200,6 +203,8 @@ spec: -log-level={{ default $root.Values.global.logLevel $root.Values.terminatingGateways.logLevel }} \ -log-json={{ $root.Values.global.logJSON }} volumeMounts: + - name: tmp + mountPath: /tmp - name: consul-service mountPath: /consul/service {{- if $root.Values.global.tls.enabled }} @@ -221,6 +226,8 @@ spec: image: {{ $root.Values.global.imageConsulDataplane | quote }} {{- include "consul.restrictedSecurityContext" $ | nindent 10 }} volumeMounts: + - name: tmp + mountPath: /tmp - name: consul-service mountPath: /consul/service readOnly: true diff --git a/charts/consul/test/terraform/aks/main.tf b/charts/consul/test/terraform/aks/main.tf index 2683bdc1a7..f9dc36a51c 100644 --- a/charts/consul/test/terraform/aks/main.tf +++ b/charts/consul/test/terraform/aks/main.tf @@ -55,7 +55,7 @@ resource "azurerm_kubernetes_cluster" "default" { location = azurerm_resource_group.default[count.index].location resource_group_name = azurerm_resource_group.default[count.index].name dns_prefix = "consul-k8s-${random_id.suffix[count.index].dec}" - kubernetes_version = "1.24.10" + kubernetes_version = var.kubernetes_version role_based_access_control_enabled = true // We're setting the network plugin and other network properties explicitly diff --git a/charts/consul/test/terraform/aks/variables.tf b/charts/consul/test/terraform/aks/variables.tf index 554d1b0965..bb8d48251a 100644 --- a/charts/consul/test/terraform/aks/variables.tf +++ b/charts/consul/test/terraform/aks/variables.tf @@ -6,6 +6,11 @@ variable "location" { description = "The location to launch this AKS cluster in." } +variable "kubernetes_version" { + default = "1.25" + description = "Kubernetes version supported on AKS" +} + variable "client_id" { default = "" description = "The client ID of the service principal to be used by Kubernetes when creating Azure resources like load balancers." diff --git a/charts/consul/test/terraform/eks/main.tf b/charts/consul/test/terraform/eks/main.tf index 3bc8b40451..efbab0e833 100644 --- a/charts/consul/test/terraform/eks/main.tf +++ b/charts/consul/test/terraform/eks/main.tf @@ -124,13 +124,12 @@ resource "aws_iam_role_policy_attachment" "csi" { } resource "aws_eks_addon" "csi-driver" { - count = var.cluster_count - cluster_name = module.eks[count.index].cluster_id - addon_name = "aws-ebs-csi-driver" - addon_version = "v1.15.0-eksbuild.1" - service_account_role_arn = aws_iam_role.csi-driver-role[count.index].arn - resolve_conflicts_on_create = "OVERWRITE" - resolve_conflicts_on_update = "OVERWRITE" + count = var.cluster_count + cluster_name = module.eks[count.index].cluster_id + addon_name = "aws-ebs-csi-driver" + addon_version = "v1.15.0-eksbuild.1" + service_account_role_arn = aws_iam_role.csi-driver-role[count.index].arn + resolve_conflicts = "OVERWRITE" } data "aws_eks_cluster" "cluster" { diff --git a/charts/consul/test/unit/connect-inject-deployment.bats b/charts/consul/test/unit/connect-inject-deployment.bats index ccc6eca68c..6db96ce8b6 100755 --- a/charts/consul/test/unit/connect-inject-deployment.bats +++ b/charts/consul/test/unit/connect-inject-deployment.bats @@ -2587,3 +2587,4 @@ reservedNameTest() { jq -r '. | select( .name == "CONSUL_TLS_SERVER_NAME").value' | tee /dev/stderr) [ "${actual}" = "server.dc1.consul" ] } + diff --git a/charts/consul/test/unit/server-config-configmap.bats b/charts/consul/test/unit/server-config-configmap.bats index 643caeb0a1..52a5c4d4c1 100755 --- a/charts/consul/test/unit/server-config-configmap.bats +++ b/charts/consul/test/unit/server-config-configmap.bats @@ -1175,7 +1175,7 @@ load _helpers local actual=$(echo $object | jq -r .audit.sink.MySink1.path | tee /dev/stderr) [ "${actual}" = "/tmp/audit.json" ] - + local actual=$(echo $object | jq -r .audit.sink.MySink3.path | tee /dev/stderr) [ "${actual}" = "/tmp/audit-3.json" ] diff --git a/charts/consul/test/unit/server-statefulset.bats b/charts/consul/test/unit/server-statefulset.bats index a60884d20c..ac9e683e73 100755 --- a/charts/consul/test/unit/server-statefulset.bats +++ b/charts/consul/test/unit/server-statefulset.bats @@ -856,8 +856,10 @@ load _helpers local expected=$(echo '{ "allowPrivilegeEscalation": false, "capabilities": { - "drop": ["ALL"] + "drop": ["ALL"], + "add": ["NET_BIND_SERVICE"] }, + "readOnlyRootFilesystem": true, "runAsNonRoot": true, "seccompProfile": { "type": "RuntimeDefault" @@ -887,8 +889,10 @@ load _helpers local expected=$(echo '{ "allowPrivilegeEscalation": false, "capabilities": { - "drop": ["ALL"] + "drop": ["ALL"], + "add": ["NET_BIND_SERVICE"] }, + "readOnlyRootFilesystem": true, "runAsNonRoot": true, "seccompProfile": { "type": "RuntimeDefault" diff --git a/charts/consul/todo.txt b/charts/consul/todo.txt new file mode 100644 index 0000000000..c79bef389b --- /dev/null +++ b/charts/consul/todo.txt @@ -0,0 +1,3 @@ + +- [x] Remove gatewayclass gatewayclassconfig bats +- [ ] Add test for each of the CRDs diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index 954680262a..380ef916de 100644 --- a/charts/consul/values.yaml +++ b/charts/consul/values.yaml @@ -66,7 +66,7 @@ global: # image: "hashicorp/consul-enterprise:1.10.0-ent" # ``` # @default: hashicorp/consul: - image: docker.mirror.hashicorp.services/hashicorppreview/consul:1.17-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul:1.16-dev # Array of objects containing image pull secret names that will be applied to each service account. # This can be used to reference image pull secrets if using a custom consul or consul-k8s-control-plane Docker image. @@ -86,7 +86,7 @@ global: # image that is used for functionality such as catalog sync. # This can be overridden per component. # @default: hashicorp/consul-k8s-control-plane: - imageK8S: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.3.0-dev + imageK8S: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.2.2-dev # The name of the datacenter that the agents should # register as. This can't be changed once the Consul cluster is up and running @@ -289,7 +289,7 @@ global: # The key within the Kubernetes secret or Vault secret key that holds the gossip # encryption key. secretKey: "" - # Override global log verbosity level for gossip-encryption-autogenerate-job pods. One of "trace", "debug", "info", "warn", or "error". + # Override global log verbosity level for `gossip-encryption-autogenerate-job` pods. One of "trace", "debug", "info", "warn", or "error". # @type: string logLevel: "" @@ -387,7 +387,7 @@ global: secretKey: null # This value defines additional annotations for - # tls init jobs. This should be formatted as a multi-line string. + # tls init jobs. Format this value as a multi-line string. # # ```yaml # annotations: | @@ -513,7 +513,7 @@ global: nodeSelector: null # This value defines additional annotations for - # acl init jobs. This should be formatted as a multi-line string. + # acl init jobs. Format this value as a multi-line string. # # ```yaml # annotations: | @@ -589,7 +589,7 @@ global: # @type: string k8sAuthMethodHost: null - # Override global log verbosity level for the create-federation-secret-job pods. One of "trace", "debug", "info", "warn", or "error". + # Override global log verbosity level for the `create-federation-secret-job` pods. One of "trace", "debug", "info", "warn", or "error". # @type: string logLevel: "" @@ -627,7 +627,7 @@ global: # The name (and tag) of the consul-dataplane Docker image used for the # connect-injected sidecar proxies and mesh, terminating, and ingress gateways. # @default: hashicorp/consul-dataplane: - imageConsulDataplane: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.3-dev + imageConsulDataplane: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.2-dev # Configuration for running this Helm chart on the Red Hat OpenShift platform. # This Helm chart currently supports OpenShift v4.x+. @@ -733,7 +733,7 @@ global: # ] # ``` # @type: array - trustedCAs: [ ] + trustedCAs: [] # Server, when enabled, configures a server cluster to run. This should # be disabled if you plan on connecting to a Consul cluster external to @@ -1226,6 +1226,43 @@ server: # @type: string caCert: null + # Settings for potentially limiting timeouts, rate limiting on clients as well + # as servers, and other settings to limit exposure too many requests, requests + # waiting for too long, and other runtime considerations. + limits: + # This object specifies configurations that limit the rate of RPC and gRPC + # requests on the Consul server. Limiting the rate of gRPC and RPC requests + # also limits HTTP requests to the Consul server. + # https://developer.hashicorp.com/consul/docs/agent/config/config-files#request_limits + requestLimits: + # Setting for disabling or enabling rate limiting. If not disabled, it + # enforces the action that will occur when RequestLimitsReadRate + # or RequestLimitsWriteRate is exceeded. The default value of "disabled" will + # prevent any rate limiting from occuring. A value of "enforce" will block + # the request from processings by returning an error. A value of + # "permissive" will not block the request and will allow the request to + # continue processing. + # @type: string + mode: "disabled" + + # Setting that controls how frequently RPC, gRPC, and HTTP + # queries are allowed to happen. In any large enough time interval, rate + # limiter limits the rate to RequestLimitsReadRate tokens per second. + # + # See https://en.wikipedia.org/wiki/Token_bucket for more about token + # buckets. + # @type: integer + readRate: -1 + + # Setting that controls how frequently RPC, gRPC, and HTTP + # writes are allowed to happen. In any large enough time interval, rate + # limiter limits the rate to RequestLimitsWriteRate tokens per second. + # + # See https://en.wikipedia.org/wiki/Token_bucket for more about token + # buckets. + # @type: integer + writeRate: -1 + # [Enterprise Only] Added in Consul 1.8, the audit object allow users to enable auditing # and configure a sink and filters for their audit logs. Please refer to # [audit logs](https://developer.hashicorp.com/consul/docs/enterprise/audit-logging) documentation @@ -1235,7 +1272,7 @@ server: # global.acls.manageSystemACLs must be enabled to use this feature. enabled: false - # A single entry of the sink object provides configuration for the destination to which Consul + # A single entry of the sink object provides configuration for the destination to which Consul # will log auditing events. # # Example: @@ -1250,7 +1287,7 @@ server: # rotate_duration: 24h # rotate_max_files: 15 # rotate_bytes: 25165824 - # + # # ``` # # The sink object supports the following keys: @@ -1280,43 +1317,6 @@ server: # @type: array sinks: [] - # Settings for potentially limiting timeouts, rate limiting on clients as well - # as servers, and other settings to limit exposure too many requests, requests - # waiting for too long, and other runtime considerations. - limits: - # This object specifies configurations that limit the rate of RPC and gRPC - # requests on the Consul server. Limiting the rate of gRPC and RPC requests - # also limits HTTP requests to the Consul server. - # https://developer.hashicorp.com/consul/docs/agent/config/config-files#request_limits - requestLimits: - # Setting for disabling or enabling rate limiting. If not disabled, it - # enforces the action that will occur when RequestLimitsReadRate - # or RequestLimitsWriteRate is exceeded. The default value of "disabled" will - # prevent any rate limiting from occuring. A value of "enforce" will block - # the request from processings by returning an error. A value of - # "permissive" will not block the request and will allow the request to - # continue processing. - # @type: string - mode: "disabled" - - # Setting that controls how frequently RPC, gRPC, and HTTP - # queries are allowed to happen. In any large enough time interval, rate - # limiter limits the rate to RequestLimitsReadRate tokens per second. - # - # See https://en.wikipedia.org/wiki/Token_bucket for more about token - # buckets. - # @type: integer - readRate: -1 - - # Setting that controls how frequently RPC, gRPC, and HTTP - # writes are allowed to happen. In any large enough time interval, rate - # limiter limits the rate to RequestLimitsWriteRate tokens per second. - # - # See https://en.wikipedia.org/wiki/Token_bucket for more about token - # buckets. - # @type: integer - writeRate: -1 - # Configuration for Consul servers when the servers are running outside of Kubernetes. # When running external servers, configuring these values is recommended # if setting `global.tls.enableAutoEncrypt` to true @@ -2206,7 +2206,7 @@ connectInject: # @type: string openshiftSCCName: "restricted-v2" - # This value defines the amount we will add to privileged container ports on gateways that use this class. + # This value defines the amount Consul will add to privileged container ports on gateways that use this class. # This is useful if you don't want to give your containers extra permissions to run privileged ports. # Example: The gateway listener is defined on port 80, but the underlying value of the port on the container # will be the 80 + the number defined below. @@ -2637,16 +2637,16 @@ connectInject: # - `consul.hashicorp.com/sidecar-proxy-lifecycle-graceful-shutdown-path` # @type: map lifecycle: - # @type: boolean - defaultEnabled: true - # @type: boolean - defaultEnableShutdownDrainListeners: true - # @type: integer - defaultShutdownGracePeriodSeconds: 30 - # @type: integer - defaultGracefulPort: 20600 - # @type: string - defaultGracefulShutdownPath: "/graceful_shutdown" + # @type: boolean + defaultEnabled: true + # @type: boolean + defaultEnableShutdownDrainListeners: true + # @type: integer + defaultShutdownGracePeriodSeconds: 30 + # @type: integer + defaultGracefulPort: 20600 + # @type: string + defaultGracefulShutdownPath: "/graceful_shutdown" # The resource settings for the Connect injected init container. If null, the resources # won't be set for the initContainer. The defaults are optimized for developer instances of @@ -2677,7 +2677,7 @@ meshGateway: # Requirements: consul 1.6.0+ if using `global.acls.manageSystemACLs``. enabled: false - # Override global log verbosity level for mesh-gateway-deployment pods. One of "trace", "debug", "info", "warn", or "error". + # Override global log verbosity level for `mesh-gateway-deployment` pods. One of "trace", "debug", "info", "warn", or "error". # @type: string logLevel: "" @@ -2893,7 +2893,7 @@ ingressGateways: # Enable ingress gateway deployment. Requires `connectInject.enabled=true`. enabled: false - # Override global log verbosity level for ingress-gateways-deployment pods. One of "trace", "debug", "info", "warn", or "error". + # Override global log verbosity level for `ingress-gateways-deployment` pods. One of "trace", "debug", "info", "warn", or "error". # @type: string logLevel: "" @@ -3212,7 +3212,7 @@ apiGateway: # The name (and tag) of the Envoy Docker image used for the # apiGateway. For other Consul compoenents, imageEnvoy has been replaced with Consul Dataplane. # @default: envoyproxy/envoy: - imageEnvoy: "envoyproxy/envoy:v1.25.1" + imageEnvoy: "envoyproxy/envoy:v1.25.9" # Override global log verbosity level for api-gateway-controller pods. One of "debug", "info", "warn", or "error". # @type: string @@ -3492,4 +3492,4 @@ telemetryCollector: # feature, in case kubernetes cluster is behind egress http proxies. Additionally, # it could be used to configure custom consul parameters. # @type: map - extraEnvironmentVars: { } + extraEnvironmentVars: {} diff --git a/cli/version/version.go b/cli/version/version.go index 952cd9ca81..fc2996ce2a 100644 --- a/cli/version/version.go +++ b/cli/version/version.go @@ -17,7 +17,7 @@ var ( // // Version must conform to the format expected by // github.com/hashicorp/go-version for tests to work. - Version = "1.3.0" + Version = "1.2.2" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release diff --git a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go index 2605991238..8083cbd81b 100644 --- a/control-plane/api-gateway/controllers/gateway_controller_integration_test.go +++ b/control-plane/api-gateway/controllers/gateway_controller_integration_test.go @@ -40,8 +40,6 @@ import ( ) func TestControllerDoesNotInfinitelyReconcile(t *testing.T) { - //TODO @apigatewayteam test is consistently failing on main after merge, fix in a follow up PR - t.Skip() s := runtime.NewScheme() require.NoError(t, clientgoscheme.AddToScheme(s)) require.NoError(t, gwv1alpha2.Install(s)) diff --git a/control-plane/api/v1alpha1/serviceresolver_types.go b/control-plane/api/v1alpha1/serviceresolver_types.go index 714cd94c2a..b7644a6ec1 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types.go +++ b/control-plane/api/v1alpha1/serviceresolver_types.go @@ -82,16 +82,6 @@ type ServiceResolverSpec struct { // LoadBalancer determines the load balancing policy and configuration for services // issuing requests to this upstream service. LoadBalancer *LoadBalancer `json:"loadBalancer,omitempty"` - // PrioritizeByLocality controls whether the locality of services within the - // local partition will be used to prioritize connectivity. - PrioritizeByLocality *ServiceResolverPrioritizeByLocality `json:"prioritizeByLocality,omitempty"` -} - -type ServiceResolverPrioritizeByLocality struct { - // Mode specifies the type of prioritization that will be performed - // when selecting nodes in the local partition. - // Valid values are: "" (default "none"), "none", and "failover". - Mode string `json:"mode,omitempty"` } type ServiceResolverRedirect struct { @@ -313,17 +303,16 @@ func (in *ServiceResolver) SyncedConditionStatus() corev1.ConditionStatus { // ToConsul converts the entry into its Consul equivalent struct. func (in *ServiceResolver) ToConsul(datacenter string) capi.ConfigEntry { return &capi.ServiceResolverConfigEntry{ - Kind: in.ConsulKind(), - Name: in.ConsulName(), - DefaultSubset: in.Spec.DefaultSubset, - Subsets: in.Spec.Subsets.toConsul(), - Redirect: in.Spec.Redirect.toConsul(), - Failover: in.Spec.Failover.toConsul(), - ConnectTimeout: in.Spec.ConnectTimeout.Duration, - RequestTimeout: in.Spec.RequestTimeout.Duration, - LoadBalancer: in.Spec.LoadBalancer.toConsul(), - PrioritizeByLocality: in.Spec.PrioritizeByLocality.toConsul(), - Meta: meta(datacenter), + Kind: in.ConsulKind(), + Name: in.ConsulName(), + DefaultSubset: in.Spec.DefaultSubset, + Subsets: in.Spec.Subsets.toConsul(), + Redirect: in.Spec.Redirect.toConsul(), + Failover: in.Spec.Failover.toConsul(), + ConnectTimeout: in.Spec.ConnectTimeout.Duration, + RequestTimeout: in.Spec.RequestTimeout.Duration, + LoadBalancer: in.Spec.LoadBalancer.toConsul(), + Meta: meta(datacenter), } } @@ -353,7 +342,6 @@ func (in *ServiceResolver) Validate(consulMeta common.ConsulMeta) error { } errs = append(errs, in.Spec.Redirect.validate(path.Child("redirect"), consulMeta)...) - errs = append(errs, in.Spec.PrioritizeByLocality.validate(path.Child("prioritizeByLocality"))...) errs = append(errs, in.Spec.Subsets.validate(path.Child("subsets"))...) errs = append(errs, in.Spec.LoadBalancer.validate(path.Child("loadBalancer"))...) errs = append(errs, in.validateEnterprise(consulMeta)...) @@ -536,16 +524,6 @@ func (in *ServiceResolverFailover) toConsul() *capi.ServiceResolverFailover { } } -func (in *ServiceResolverPrioritizeByLocality) toConsul() *capi.ServiceResolverPrioritizeByLocality { - if in == nil { - return nil - } - - return &capi.ServiceResolverPrioritizeByLocality{ - Mode: in.Mode, - } -} - func (in ServiceResolverFailoverTarget) toConsul() capi.ServiceResolverFailoverTarget { return capi.ServiceResolverFailoverTarget{ Service: in.Service, @@ -655,25 +633,6 @@ func (in *ServiceResolverFailover) isEmpty() bool { return in.Service == "" && in.ServiceSubset == "" && in.Namespace == "" && len(in.Datacenters) == 0 && len(in.Targets) == 0 && in.Policy == nil && in.SamenessGroup == "" } -func (in *ServiceResolverPrioritizeByLocality) validate(path *field.Path) field.ErrorList { - var errs field.ErrorList - - if in == nil { - return nil - } - - switch in.Mode { - case "": - case "none": - case "failover": - default: - asJSON, _ := json.Marshal(in) - errs = append(errs, field.Invalid(path, string(asJSON), - "mode must be one of '', 'none', or 'failover'")) - } - return errs -} - func (in *ServiceResolverFailover) validate(path *field.Path, consulMeta common.ConsulMeta) field.ErrorList { var errs field.ErrorList if in.isEmpty() { diff --git a/control-plane/api/v1alpha1/serviceresolver_types_test.go b/control-plane/api/v1alpha1/serviceresolver_types_test.go index 11751aaa2a..70791b606c 100644 --- a/control-plane/api/v1alpha1/serviceresolver_types_test.go +++ b/control-plane/api/v1alpha1/serviceresolver_types_test.go @@ -66,9 +66,6 @@ func TestServiceResolver_MatchesConsul(t *testing.T) { Datacenter: "redirect_datacenter", Peer: "redirect_peer", }, - PrioritizeByLocality: &ServiceResolverPrioritizeByLocality{ - Mode: "failover", - }, Failover: map[string]ServiceResolverFailover{ "failover1": { Service: "failover1", @@ -151,9 +148,6 @@ func TestServiceResolver_MatchesConsul(t *testing.T) { Datacenter: "redirect_datacenter", Peer: "redirect_peer", }, - PrioritizeByLocality: &capi.ServiceResolverPrioritizeByLocality{ - Mode: "failover", - }, Failover: map[string]capi.ServiceResolverFailover{ "failover1": { Service: "failover1", @@ -285,9 +279,6 @@ func TestServiceResolver_ToConsul(t *testing.T) { Datacenter: "redirect_datacenter", Partition: "redirect_partition", }, - PrioritizeByLocality: &ServiceResolverPrioritizeByLocality{ - Mode: "none", - }, Failover: map[string]ServiceResolverFailover{ "failover1": { Service: "failover1", @@ -370,9 +361,6 @@ func TestServiceResolver_ToConsul(t *testing.T) { Datacenter: "redirect_datacenter", Partition: "redirect_partition", }, - PrioritizeByLocality: &capi.ServiceResolverPrioritizeByLocality{ - Mode: "none", - }, Failover: map[string]capi.ServiceResolverFailover{ "failover1": { Service: "failover1", @@ -898,22 +886,6 @@ func TestServiceResolver_Validate(t *testing.T) { "spec.failover[failB].namespace: Invalid value: \"namespace-b\": Consul Enterprise namespaces must be enabled to set failover.namespace", }, }, - "prioritize by locality none": { - input: &ServiceResolver{ - ObjectMeta: metav1.ObjectMeta{ - Name: "foo", - }, - Spec: ServiceResolverSpec{ - PrioritizeByLocality: &ServiceResolverPrioritizeByLocality{ - Mode: "bad", - }, - }, - }, - namespacesEnabled: false, - expectedErrMsgs: []string{ - "mode must be one of '', 'none', or 'failover'", - }, - }, } for name, testCase := range cases { t.Run(name, func(t *testing.T) { diff --git a/control-plane/api/v1alpha1/zz_generated.deepcopy.go b/control-plane/api/v1alpha1/zz_generated.deepcopy.go index 05000031ad..d9217fdcf7 100644 --- a/control-plane/api/v1alpha1/zz_generated.deepcopy.go +++ b/control-plane/api/v1alpha1/zz_generated.deepcopy.go @@ -2618,21 +2618,6 @@ func (in *ServiceResolverList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ServiceResolverPrioritizeByLocality) DeepCopyInto(out *ServiceResolverPrioritizeByLocality) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceResolverPrioritizeByLocality. -func (in *ServiceResolverPrioritizeByLocality) DeepCopy() *ServiceResolverPrioritizeByLocality { - if in == nil { - return nil - } - out := new(ServiceResolverPrioritizeByLocality) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServiceResolverRedirect) DeepCopyInto(out *ServiceResolverRedirect) { *out = *in @@ -2677,11 +2662,6 @@ func (in *ServiceResolverSpec) DeepCopyInto(out *ServiceResolverSpec) { *out = new(LoadBalancer) (*in).DeepCopyInto(*out) } - if in.PrioritizeByLocality != nil { - in, out := &in.PrioritizeByLocality, &out.PrioritizeByLocality - *out = new(ServiceResolverPrioritizeByLocality) - **out = **in - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceResolverSpec. diff --git a/control-plane/build-support/functions/10-util.sh b/control-plane/build-support/functions/10-util.sh index 3bc87124d9..d22d15f9a8 100644 --- a/control-plane/build-support/functions/10-util.sh +++ b/control-plane/build-support/functions/10-util.sh @@ -733,7 +733,11 @@ function set_changelog { rel_date="$3" fi local last_release_date_git_tag=$4 - local preReleaseVersion="-$5" + + local preReleaseVersion + if test -n "$5"; then + local preReleaseVersion="-$5" + fi if test -z "${version}"; then err "ERROR: Must specify a version to put into the changelog" diff --git a/control-plane/build-support/functions/20-build.sh b/control-plane/build-support/functions/20-build.sh index dac626b88f..e9540956c9 100644 --- a/control-plane/build-support/functions/20-build.sh +++ b/control-plane/build-support/functions/20-build.sh @@ -188,7 +188,7 @@ function build_consul_local { # build with go install. # The GOXPARALLEL environment variable is used if set - if [ "${GOTAGS:-}" == "fips" ]; then + if [ $GOTAGS == "fips" ]; then CGO_ENABLED=1 else CGO_ENABLED=0 diff --git a/control-plane/build-support/scripts/consul-version.sh b/control-plane/build-support/scripts/consul-version.sh index faaed33b20..4761e3e923 100755 --- a/control-plane/build-support/scripts/consul-version.sh +++ b/control-plane/build-support/scripts/consul-version.sh @@ -6,6 +6,7 @@ VERSION=$(yq .global.image $FILE) if [[ "${VERSION}" == *"consul-enterprise:"* ]]; then VERSION=$(echo ${VERSION} | sed "s/consul-enterprise:/consul:/g") + VERSION=$(echo ${VERSION} | sed "s/\-ent//") fi echo "${VERSION}" diff --git a/control-plane/catalog/to-consul/resource.go b/control-plane/catalog/to-consul/resource.go index 2d29d6c15a..0c319d90ee 100644 --- a/control-plane/catalog/to-consul/resource.go +++ b/control-plane/catalog/to-consul/resource.go @@ -512,7 +512,7 @@ func (t *ServiceResource) generateRegistrations(key string) { r.Service.ID = serviceID(r.Service.Service, ip) r.Service.Address = ip // Adding information about service weight. - // Overrides the existing weight if present. + // Overrides the existing weight if present if weight, ok := svc.Annotations[annotationServiceWeight]; ok && weight != "" { weightI, err := getServiceWeight(weight) if err == nil { @@ -561,7 +561,7 @@ func (t *ServiceResource) generateRegistrations(key string) { r.Service.Address = addr // Adding information about service weight. - // Overrides the existing weight if present. + // Overrides the existing weight if present if weight, ok := svc.Annotations[annotationServiceWeight]; ok && weight != "" { weightI, err := getServiceWeight(weight) if err == nil { @@ -1028,7 +1028,7 @@ func consulHealthCheckID(k8sNS string, serviceID string) string { // Calculates the passing service weight. func getServiceWeight(weight string) (int, error) { - // error validation if the input param is a number. + // error validation if the input param is a number weightI, err := strconv.Atoi(weight) if err != nil { return -1, err diff --git a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml index 0146eca982..e869982b59 100644 --- a/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml +++ b/control-plane/config/crd/bases/consul.hashicorp.com_serviceresolvers.yaml @@ -223,16 +223,6 @@ spec: type: integer type: object type: object - prioritizeByLocality: - description: PrioritizeByLocality controls whether the locality of - services within the local partition will be used to prioritize connectivity. - properties: - mode: - description: 'Mode specifies the type of prioritization that will - be performed when selecting nodes in the local partition. Valid - values are: "" (default "none"), "none", and "failover".' - type: string - type: object redirect: description: Redirect when configured, all attempts to resolve the service this resolver defines will be substituted for the supplied diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go index 3f139c2662..fb44a2a5ba 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller.go @@ -317,20 +317,6 @@ func (r *Controller) registerServicesAndHealthCheck(apiClient *api.Client, pod c return nil } -func parseLocality(node corev1.Node) *api.Locality { - region := node.Labels[corev1.LabelTopologyRegion] - zone := node.Labels[corev1.LabelTopologyZone] - - if region == "" { - return nil - } - - return &api.Locality{ - Region: region, - Zone: zone, - } -} - // registerGateway creates Consul registrations for the Connect Gateways and registers them with Consul. // It also upserts a Kubernetes health check for the service based on whether the endpoint address is ready. func (r *Controller) registerGateway(apiClient *api.Client, pod corev1.Pod, serviceEndpoints corev1.Endpoints, healthStatus string, endpointAddressMap map[string]bool) error { @@ -418,11 +404,6 @@ func (r *Controller) createServiceRegistrations(pod corev1.Pod, serviceEndpoints } } - var node corev1.Node - // Ignore errors because we don't want failures to block running services. - _ = r.Client.Get(context.Background(), types.NamespacedName{Name: pod.Spec.NodeName, Namespace: pod.Namespace}, &node) - locality := parseLocality(node) - // We only want that annotation to be present when explicitly overriding the consul svc name // Otherwise, the Consul service name should equal the Kubernetes Service name. // The service name in Consul defaults to the Endpoints object name, and is overridden by the pod @@ -458,7 +439,6 @@ func (r *Controller) createServiceRegistrations(pod corev1.Pod, serviceEndpoints Meta: meta, Namespace: consulNS, Tags: tags, - Locality: locality, } serviceRegistration := &api.CatalogRegistration{ Node: common.ConsulNodeNameFromK8sNode(pod.Spec.NodeName), @@ -535,8 +515,6 @@ func (r *Controller) createServiceRegistrations(pod corev1.Pod, serviceEndpoints Namespace: consulNS, Proxy: proxyConfig, Tags: tags, - // Sidecar locality (not proxied service locality) is used for locality-aware routing. - Locality: locality, } // A user can enable/disable tproxy for an entire namespace. diff --git a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go index 2cec69dd0a..add93cf8e1 100644 --- a/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go +++ b/control-plane/connect-inject/controllers/endpoints/endpoints_controller_test.go @@ -1941,17 +1941,6 @@ func TestReconcileCreateEndpoint(t *testing.T) { pod1.Annotations[constants.AnnotationUpstreams] = "upstream1:1234" pod1.Annotations[constants.AnnotationEnableMetrics] = "true" pod1.Annotations[constants.AnnotationPrometheusScrapePort] = "12345" - pod1.Spec.NodeName = "my-node" - node := &corev1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-node", - Namespace: "default", - Labels: map[string]string{ - corev1.LabelTopologyRegion: "us-west-1", - corev1.LabelTopologyZone: "us-west-1a", - }, - }, - } endpoint := &corev1.Endpoints{ ObjectMeta: metav1.ObjectMeta{ Name: "service-created", @@ -1972,7 +1961,7 @@ func TestReconcileCreateEndpoint(t *testing.T) { }, }, } - return []runtime.Object{pod1, node, endpoint} + return []runtime.Object{pod1, endpoint} }, expectedConsulSvcInstances: []*api.CatalogService{ { @@ -1992,10 +1981,6 @@ func TestReconcileCreateEndpoint(t *testing.T) { }, ServiceTags: []string{"abc,123", "pod1"}, ServiceProxy: &api.AgentServiceConnectProxyConfig{}, - ServiceLocality: &api.Locality{ - Region: "us-west-1", - Zone: "us-west-1a", - }, }, }, expectedProxySvcInstances: []*api.CatalogService{ @@ -2021,10 +2006,6 @@ func TestReconcileCreateEndpoint(t *testing.T) { "envoy_telemetry_collector_bind_socket_dir": "/consul/connect-inject", }, }, - ServiceLocality: &api.Locality{ - Region: "us-west-1", - Zone: "us-west-1a", - }, ServiceMeta: map[string]string{ "name": "abc", "version": "2", @@ -2212,7 +2193,6 @@ func TestReconcileCreateEndpoint(t *testing.T) { require.Equal(t, tt.expectedConsulSvcInstances[i].ServicePort, instance.ServicePort) require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceMeta, instance.ServiceMeta) require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceTags, instance.ServiceTags) - require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceLocality, instance.ServiceLocality) require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceTaggedAddresses, instance.ServiceTaggedAddresses) require.Equal(t, tt.expectedConsulSvcInstances[i].ServiceProxy, instance.ServiceProxy) if tt.nodeMeta != nil { @@ -2229,7 +2209,6 @@ func TestReconcileCreateEndpoint(t *testing.T) { require.Equal(t, tt.expectedProxySvcInstances[i].ServicePort, instance.ServicePort) require.Equal(t, tt.expectedProxySvcInstances[i].ServiceMeta, instance.ServiceMeta) require.Equal(t, tt.expectedProxySvcInstances[i].ServiceTags, instance.ServiceTags) - require.Equal(t, tt.expectedProxySvcInstances[i].ServiceLocality, instance.ServiceLocality) if tt.nodeMeta != nil { require.Equal(t, tt.expectedProxySvcInstances[i].NodeMeta, instance.NodeMeta) } @@ -2260,36 +2239,6 @@ func TestReconcileCreateEndpoint(t *testing.T) { } } -func TestParseLocality(t *testing.T) { - t.Run("no labels", func(t *testing.T) { - n := corev1.Node{} - require.Nil(t, parseLocality(n)) - }) - - t.Run("zone only", func(t *testing.T) { - n := corev1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - corev1.LabelTopologyZone: "us-west-1a", - }, - }, - } - require.Nil(t, parseLocality(n)) - }) - - t.Run("everything", func(t *testing.T) { - n := corev1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - corev1.LabelTopologyRegion: "us-west-1", - corev1.LabelTopologyZone: "us-west-1a", - }, - }, - } - require.Equal(t, &api.Locality{Region: "us-west-1", Zone: "us-west-1a"}, parseLocality(n)) - }) -} - // Tests updating an Endpoints object. // - Tests updates via the register codepath: // - When an address in an Endpoint is updated, that the corresponding service instance in Consul is updated. diff --git a/control-plane/connect-inject/controllers/peering/peering_acceptor_controller_test.go b/control-plane/connect-inject/controllers/peering/peering_acceptor_controller_test.go index 5a0d37135a..601be1a833 100644 --- a/control-plane/connect-inject/controllers/peering/peering_acceptor_controller_test.go +++ b/control-plane/connect-inject/controllers/peering/peering_acceptor_controller_test.go @@ -22,7 +22,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" "k8s.io/utils/pointer" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" @@ -501,7 +500,8 @@ func TestReconcile_CreateUpdatePeeringAcceptor(t *testing.T) { // Create fake k8s client k8sObjects := append(tt.k8sObjects(), &ns) - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringAcceptor{}, &v1alpha1.PeeringAcceptorList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() @@ -622,7 +622,8 @@ func TestReconcile_DeletePeeringAcceptor(t *testing.T) { k8sObjects := []runtime.Object{&ns, acceptor} // Add peering types to the scheme. - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringAcceptor{}, &v1alpha1.PeeringAcceptorList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() @@ -768,7 +769,8 @@ func TestReconcile_VersionAnnotation(t *testing.T) { // Create fake k8s client k8sObjects := []runtime.Object{acceptor, secret, ns} - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringAcceptor{}, &v1alpha1.PeeringAcceptorList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() @@ -1080,7 +1082,8 @@ func TestAcceptorUpdateStatus(t *testing.T) { k8sObjects = append(k8sObjects, tt.peeringAcceptor) // Add peering types to the scheme. - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringAcceptor{}, &v1alpha1.PeeringAcceptorList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() // Create the peering acceptor controller. @@ -1192,7 +1195,8 @@ func TestAcceptorUpdateStatusError(t *testing.T) { k8sObjects = append(k8sObjects, tt.acceptor) // Add peering types to the scheme. - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringAcceptor{}, &v1alpha1.PeeringAcceptorList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() // Create the peering acceptor controller. @@ -1476,7 +1480,8 @@ func TestAcceptor_RequestsForPeeringTokens(t *testing.T) { for name, tt := range cases { t.Run(name, func(t *testing.T) { - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringAcceptor{}, &v1alpha1.PeeringAcceptorList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(tt.secret, &tt.acceptors).Build() controller := AcceptorController{ diff --git a/control-plane/connect-inject/controllers/peering/peering_dialer_controller_test.go b/control-plane/connect-inject/controllers/peering/peering_dialer_controller_test.go index 8d999cbf2a..c142cd9eee 100644 --- a/control-plane/connect-inject/controllers/peering/peering_dialer_controller_test.go +++ b/control-plane/connect-inject/controllers/peering/peering_dialer_controller_test.go @@ -24,7 +24,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/kubernetes/scheme" "k8s.io/utils/pointer" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" @@ -280,9 +279,11 @@ func TestReconcile_CreateUpdatePeeringDialer(t *testing.T) { var encodedPeeringToken string if tt.peeringName != "" { // Create the initial token. - baseToken, _, err := acceptorClient.Peerings().GenerateToken(context.Background(), api.PeeringGenerateTokenRequest{PeerName: tt.peeringName}, nil) - require.NoError(t, err) - encodedPeeringToken = baseToken.PeeringToken + retry.Run(t, func(r *retry.R) { + baseToken, _, err := acceptorClient.Peerings().GenerateToken(context.Background(), api.PeeringGenerateTokenRequest{PeerName: tt.peeringName}, nil) + require.NoError(r, err) + encodedPeeringToken = baseToken.PeeringToken + }) } // If the peering is not supposed to already exist in Consul, then create a secret with the generated token. @@ -314,7 +315,8 @@ func TestReconcile_CreateUpdatePeeringDialer(t *testing.T) { secret.SetResourceVersion("latest-version") k8sObjects = append(k8sObjects, secret) } - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringDialer{}, &v1alpha1.PeeringDialerList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() @@ -482,8 +484,11 @@ func TestReconcile_VersionAnnotationPeeringDialer(t *testing.T) { // Create a peering connection in Consul by generating and establishing a peering connection before calling // Reconcile(). // Generate a token. - generatedToken, _, err := acceptorClient.Peerings().GenerateToken(context.Background(), api.PeeringGenerateTokenRequest{PeerName: "peering"}, nil) - require.NoError(t, err) + var generatedToken *api.PeeringGenerateTokenResponse + retry.Run(t, func(r *retry.R) { + generatedToken, _, err = acceptorClient.Peerings().GenerateToken(context.Background(), api.PeeringGenerateTokenRequest{PeerName: "peering"}, nil) + require.NoError(r, err) + }) // Create test consul server. var testServerCfg *testutil.TestServerConfig @@ -524,7 +529,8 @@ func TestReconcile_VersionAnnotationPeeringDialer(t *testing.T) { secret.SetResourceVersion("latest-version") k8sObjects = append(k8sObjects, secret) - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringDialer{}, &v1alpha1.PeeringDialerList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() @@ -740,7 +746,8 @@ func TestReconcileDeletePeeringDialer(t *testing.T) { k8sObjects := []runtime.Object{ns, dialer} // Add peering types to the scheme. - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringDialer{}, &v1alpha1.PeeringDialerList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() @@ -881,7 +888,8 @@ func TestDialerUpdateStatus(t *testing.T) { k8sObjects = append(k8sObjects, tt.peeringDialer) // Add peering types to the scheme. - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringDialer{}, &v1alpha1.PeeringDialerList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() // Create the peering dialer controller. @@ -993,7 +1001,8 @@ func TestDialerUpdateStatusError(t *testing.T) { k8sObjects = append(k8sObjects, tt.dialer) // Add peering types to the scheme. - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringDialer{}, &v1alpha1.PeeringDialerList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(k8sObjects...).Build() // Create the peering dialer controller. @@ -1277,7 +1286,8 @@ func TestDialer_RequestsForPeeringTokens(t *testing.T) { for name, tt := range cases { t.Run(name, func(t *testing.T) { - s := scheme.Scheme + s := runtime.NewScheme() + corev1.AddToScheme(s) s.AddKnownTypes(v1alpha1.GroupVersion, &v1alpha1.PeeringDialer{}, &v1alpha1.PeeringDialerList{}) fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(tt.secret, &tt.dialers).Build() controller := PeeringDialerController{ diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go index 68f57ed061..ad2e07fffa 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar.go @@ -98,6 +98,29 @@ func (w *MeshWebhook) consulDataplaneSidecar(namespace corev1.Namespace, pod cor Name: "DP_SERVICE_NODE_NAME", Value: "$(NODE_NAME)-virtual", }, + // The pod name isn't known currently, so we must rely on the environment variable to fill it in rather than using args. + { + Name: "POD_NAME", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.name"}, + }, + }, + { + Name: "POD_NAMESPACE", + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.namespace"}, + }, + }, + { + Name: "DP_CREDENTIAL_LOGIN_META", + Value: "pod=$(POD_NAMESPACE)/$(POD_NAME)", + }, + // This entry exists to support certain versions of consul dataplane, where environment variable entries + // utilize this numbered notation to indicate individual KV pairs in a map. + { + Name: "DP_CREDENTIAL_LOGIN_META1", + Value: "pod=$(POD_NAMESPACE)/$(POD_NAME)", + }, }, VolumeMounts: []corev1.VolumeMount{ { @@ -208,7 +231,7 @@ func (w *MeshWebhook) getContainerSidecarArgs(namespace corev1.Namespace, mpi mu "-credential-type=login", "-login-auth-method="+w.AuthMethod, "-login-bearer-token-path="+bearerTokenFile, - "-login-meta="+fmt.Sprintf("pod=%s/%s", namespace.Name, pod.Name), + // We don't know the pod name at this time, so we must use environment variables to populate the login-meta instead. ) if w.EnableNamespaces { if w.EnableK8SNSMirroring { diff --git a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go index d83b094d99..f89703d5ad 100644 --- a/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go +++ b/control-plane/connect-inject/webhook/consul_dataplane_sidecar_test.go @@ -42,7 +42,7 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.AuthMethod = "test-auth-method" }, additionalExpCmdArgs: " -credential-type=login -login-auth-method=test-auth-method -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token " + - "-login-meta=pod=k8snamespace/test-pod -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", + "-tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with ACLs and namespace mirroring": { webhookSetupFunc: func(w *MeshWebhook) { @@ -51,7 +51,7 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.EnableK8SNSMirroring = true }, additionalExpCmdArgs: " -credential-type=login -login-auth-method=test-auth-method -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token " + - "-login-meta=pod=k8snamespace/test-pod -login-namespace=default -service-namespace=k8snamespace -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", + "-login-namespace=default -service-namespace=k8snamespace -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with ACLs and single destination namespace": { webhookSetupFunc: func(w *MeshWebhook) { @@ -60,7 +60,7 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.ConsulDestinationNamespace = "test-ns" }, additionalExpCmdArgs: " -credential-type=login -login-auth-method=test-auth-method -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token " + - "-login-meta=pod=k8snamespace/test-pod -login-namespace=test-ns -service-namespace=test-ns -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", + "-login-namespace=test-ns -service-namespace=test-ns -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with ACLs and partitions": { webhookSetupFunc: func(w *MeshWebhook) { @@ -68,7 +68,7 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { w.ConsulPartition = "test-part" }, additionalExpCmdArgs: " -credential-type=login -login-auth-method=test-auth-method -login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token " + - "-login-meta=pod=k8snamespace/test-pod -login-partition=test-part -service-partition=test-part -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", + "-login-partition=test-part -service-partition=test-part -tls-disabled -graceful-port=20600 -telemetry-prom-scrape-path=/metrics", }, "with TLS and CA cert provided": { webhookSetupFunc: func(w *MeshWebhook) { @@ -219,11 +219,17 @@ func TestHandlerConsulDataplaneSidecar(t *testing.T) { } require.Equal(t, expectedProbe, container.ReadinessProbe) require.Nil(t, container.StartupProbe) - require.Len(t, container.Env, 3) + require.Len(t, container.Env, 7) require.Equal(t, container.Env[0].Name, "TMPDIR") require.Equal(t, container.Env[0].Value, "/consul/connect-inject") require.Equal(t, container.Env[2].Name, "DP_SERVICE_NODE_NAME") require.Equal(t, container.Env[2].Value, "$(NODE_NAME)-virtual") + require.Equal(t, container.Env[3].Name, "POD_NAME") + require.Equal(t, container.Env[4].Name, "POD_NAMESPACE") + require.Equal(t, container.Env[5].Name, "DP_CREDENTIAL_LOGIN_META") + require.Equal(t, container.Env[5].Value, "pod=$(POD_NAMESPACE)/$(POD_NAME)") + require.Equal(t, container.Env[6].Name, "DP_CREDENTIAL_LOGIN_META1") + require.Equal(t, container.Env[6].Value, "pod=$(POD_NAMESPACE)/$(POD_NAME)") }) } } @@ -631,10 +637,10 @@ func TestHandlerConsulDataplaneSidecar_Multiport(t *testing.T) { expArgs = []string{ "-addresses 1.1.1.1 -grpc-port=8502 -proxy-service-id-path=/consul/connect-inject/proxyid-web " + "-log-level=info -log-json=false -envoy-concurrency=0 -credential-type=login -login-auth-method=test-auth-method " + - "-login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token -login-meta=pod=k8snamespace/test-pod -tls-disabled -envoy-admin-bind-port=19000 -graceful-port=20600 -telemetry-prom-scrape-path=/metrics -- --base-id 0", + "-login-bearer-token-path=/var/run/secrets/kubernetes.io/serviceaccount/token -tls-disabled -envoy-admin-bind-port=19000 -graceful-port=20600 -telemetry-prom-scrape-path=/metrics -- --base-id 0", "-addresses 1.1.1.1 -grpc-port=8502 -proxy-service-id-path=/consul/connect-inject/proxyid-web-admin " + "-log-level=info -log-json=false -envoy-concurrency=0 -credential-type=login -login-auth-method=test-auth-method " + - "-login-bearer-token-path=/consul/serviceaccount-web-admin/token -login-meta=pod=k8snamespace/test-pod -tls-disabled -envoy-admin-bind-port=19001 -graceful-port=20601 -telemetry-prom-scrape-path=/metrics -- --base-id 1", + "-login-bearer-token-path=/consul/serviceaccount-web-admin/token -tls-disabled -envoy-admin-bind-port=19001 -graceful-port=20601 -telemetry-prom-scrape-path=/metrics -- --base-id 1", } } expSAVolumeMounts := []corev1.VolumeMount{ diff --git a/control-plane/version/version.go b/control-plane/version/version.go index 952cd9ca81..fc2996ce2a 100644 --- a/control-plane/version/version.go +++ b/control-plane/version/version.go @@ -17,7 +17,7 @@ var ( // // Version must conform to the format expected by // github.com/hashicorp/go-version for tests to work. - Version = "1.3.0" + Version = "1.2.2" // A pre-release marker for the version. If this is "" (empty string) // then it means that it is a final release. Otherwise, this is a pre-release diff --git a/hack/aws-acceptance-test-cleanup/main.go b/hack/aws-acceptance-test-cleanup/main.go index e4094ec47e..d62e5e4405 100644 --- a/hack/aws-acceptance-test-cleanup/main.go +++ b/hack/aws-acceptance-test-cleanup/main.go @@ -25,7 +25,6 @@ import ( "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/eks" "github.com/aws/aws-sdk-go/service/elb" - "github.com/aws/aws-sdk-go/service/iam" "github.com/cenkalti/backoff/v4" ) @@ -39,11 +38,6 @@ var ( errNotDestroyed = errors.New("not yet destroyed") ) -type oidc struct { - arn string - buildUrl string -} - func main() { flag.BoolVar(&flagAutoApprove, "auto-approve", false, "Skip interactive approval before destroying.") flag.Parse() @@ -74,106 +68,6 @@ func realMain(ctx context.Context) error { eksClient := eks.New(clientSession, awsCfg) ec2Client := ec2.New(clientSession, awsCfg) elbClient := elb.New(clientSession, awsCfg) - iamClient := iam.New(clientSession, awsCfg) - - // Find OIDC providers to delete. - oidcProvidersOutput, err := iamClient.ListOpenIDConnectProvidersWithContext(ctx, &iam.ListOpenIDConnectProvidersInput{}) - if err != nil { - return err - } else if oidcProvidersOutput == nil { - return fmt.Errorf("nil output for OIDC Providers") - } - - toDeleteOidcArns := []*oidc{} - for _, providerEntry := range oidcProvidersOutput.OpenIDConnectProviderList { - arnString := "" - if providerEntry.Arn != nil { - arnString = *providerEntry.Arn - } - // Check if it's older than 8 hours. - older, err := oidcOlderThanEightHours(ctx, iamClient, providerEntry.Arn) - if err != nil { - return err - } - // Only add to delete list if it's older than 8 hours and has a buildURL tag. - if older { - output, err := iamClient.ListOpenIDConnectProviderTags(&iam.ListOpenIDConnectProviderTagsInput{OpenIDConnectProviderArn: providerEntry.Arn}) - if err != nil { - return err - } - for _, tag := range output.Tags { - if tag.Key != nil && *tag.Key == buildURLTag { - var buildUrl string - if tag.Value != nil { - buildUrl = *tag.Value - } - toDeleteOidcArns = append(toDeleteOidcArns, &oidc{arn: arnString, buildUrl: buildUrl}) - } - } - } else { - fmt.Printf("Skipping OIDC provider: %s because it's not over 8 hours old\n", arnString) - } - } - - oidcProvidersExist := true - if len(toDeleteOidcArns) == 0 { - fmt.Println("Found no OIDC Providers to clean up") - oidcProvidersExist = false - } else { - // Print out the OIDC Provider arns and the build tags. - var oidcPrint string - for _, oidcProvider := range toDeleteOidcArns { - oidcPrint += fmt.Sprintf("- %s (%s)\n", oidcProvider.arn, oidcProvider.buildUrl) - } - - fmt.Printf("Found OIDC Providers:\n%s", oidcPrint) - } - - // Check for approval. - if !flagAutoApprove && oidcProvidersExist { - type input struct { - text string - err error - } - inputCh := make(chan input) - - // Read input in a goroutine so we can also exit if we get a Ctrl-C - // (see select{} below). - go func() { - reader := bufio.NewReader(os.Stdin) - fmt.Println("\nDo you want to delete these OIDC Providers (y/n)?") - inputStr, err := reader.ReadString('\n') - if err != nil { - inputCh <- input{err: err} - return - } - inputCh <- input{text: inputStr} - }() - - select { - case in := <-inputCh: - if in.err != nil { - return in.err - } - inputTrimmed := strings.TrimSpace(in.text) - if inputTrimmed != "y" && inputTrimmed != "yes" { - return errors.New("exiting after negative") - } - case <-ctx.Done(): - return errors.New("context cancelled") - } - } - - // Actually delete the OIDC providers. - for _, oidcArn := range toDeleteOidcArns { - fmt.Printf("Deleting OIDC provider: %s\n", oidcArn.arn) - _, err := iamClient.DeleteOpenIDConnectProviderWithContext(ctx, &iam.DeleteOpenIDConnectProviderInput{ - OpenIDConnectProviderArn: &oidcArn.arn, - }) - if err != nil { - return err - } - } // Find VPCs to delete. Most resources we create belong to a VPC, except // for IAM resources, and so if there are no VPCs, that means all leftover resources have been deleted. @@ -643,25 +537,6 @@ func realMain(ctx context.Context) error { return nil } -// oidcOlderThanEightHours checks if the oidc provider is older than 8 hours. -func oidcOlderThanEightHours(ctx context.Context, iamClient *iam.IAM, oidcArn *string) (bool, error) { - fullOidc, err := iamClient.GetOpenIDConnectProviderWithContext(ctx, &iam.GetOpenIDConnectProviderInput{ - OpenIDConnectProviderArn: oidcArn, - }) - if err != nil { - return false, err - } - if fullOidc != nil { - if fullOidc.CreateDate != nil { - d := time.Since(*fullOidc.CreateDate) - if d.Hours() > 8 { - return true, nil - } - } - } - return false, nil -} - func vpcNameAndBuildURL(vpc *ec2.Vpc) (string, string) { var vpcName string var buildURL string From 0116964bebfa1fc84324f7135324da84330b77b9 Mon Sep 17 00:00:00 2001 From: Jitendra Gangwar Date: Tue, 29 Aug 2023 03:24:49 +0000 Subject: [PATCH 120/120] backport of commit d4ab6b53b96371ca6cde915cdfc9cd0397cb4e60 --- .../consul/test/unit/server-statefulset.bats | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/charts/consul/test/unit/server-statefulset.bats b/charts/consul/test/unit/server-statefulset.bats index ac9e683e73..32b3fcab36 100755 --- a/charts/consul/test/unit/server-statefulset.bats +++ b/charts/consul/test/unit/server-statefulset.bats @@ -677,6 +677,41 @@ load _helpers [ "${actual}" = "/v1/agent/metrics" ] } +@test "server/StatefulSet: when global.metrics.enableAgentMetrics=true, adds prometheus scheme=http annotation" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.metrics.enabled=true' \ + --set 'global.metrics.enableAgentMetrics=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations."prometheus.io/scheme"' | tee /dev/stderr) + [ "${actual}" = "http" ] +} + +@test "server/StatefulSet: when global.metrics.enableAgentMetrics=true and global.tls.enabled=true, adds prometheus port=8501 annotation" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.metrics.enabled=true' \ + --set 'global.metrics.enableAgentMetrics=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations."prometheus.io/port"' | tee /dev/stderr) + [ "${actual}" = "8501" ] +} + +@test "server/StatefulSet: when global.metrics.enableAgentMetrics=true and global.tls.enabled=true, adds prometheus scheme=https annotation" { + cd `chart_dir` + local actual=$(helm template \ + -s templates/server-statefulset.yaml \ + --set 'global.metrics.enabled=true' \ + --set 'global.metrics.enableAgentMetrics=true' \ + --set 'global.tls.enabled=true' \ + . | tee /dev/stderr | + yq -r '.spec.template.metadata.annotations."prometheus.io/scheme"' | tee /dev/stderr) + [ "${actual}" = "https" ] +} + #-------------------------------------------------------------------- # config-configmap