From cc3cfb652f2ae6c46e3a33a8cd563d9fcbf36670 Mon Sep 17 00:00:00 2001 From: Melisa Griffin Date: Tue, 13 Feb 2024 17:39:58 +0000 Subject: [PATCH] backport of commit 768ea38ffbec6c7ee66b7a891f0a1541fa16958d --- .../workflows/weekly-acceptance-1-4-0-rc1.yml | 28 --- .github/workflows/weekly-acceptance-1-4-x.yml | 28 --- .../framework/connhelper/connect_helper.go | 2 +- acceptance/framework/resource/helpers.go | 94 ------- acceptance/go.mod | 10 +- acceptance/go.sum | 25 +- .../api-gateway_v2/api_gateway_v2_test.go | 186 -------------- acceptance/tests/api-gateway_v2/helpers.go | 123 --------- acceptance/tests/api-gateway_v2/main_test.go | 24 -- .../bases/api-gateway-v2/apigateway.yaml | 16 -- .../bases/api-gateway-v2/certificate.yaml | 11 - .../bases/api-gateway-v2/gatewayclass.yaml | 13 - .../api-gateway-v2/gatewayclassconfig.yaml | 7 - .../bases/api-gateway-v2/kustomization.yaml | 8 - .../bases/api-gateway-v2/tcproute.yaml | 10 - acceptance/tests/mesh_v2/mesh_inject_test.go | 1 + acceptance/tests/tenancy_v2/namespace_test.go | 62 ----- charts/consul/Chart.yaml | 10 +- .../templates/connect-inject-clusterrole.yaml | 2 - charts/consul/templates/crd-apigateways.yaml | 131 +++------- charts/consul/templates/crd-grpcroutes.yaml | 23 +- charts/consul/templates/crd-httproutes.yaml | 23 +- charts/consul/templates/crd-tcproutes.yaml | 23 +- .../templates/crd-trafficpermissions.yaml | 72 +++--- .../gateway-resources-configmap.yaml | 69 +---- .../unit/gateway-resources-configmap.bats | 237 +----------------- charts/consul/values.yaml | 6 +- cli/version/version.go | 2 +- .../v2beta1/traffic_permissions_types_test.go | 2 +- control-plane/api/common/common.go | 3 +- .../api/mesh/v2beta1/api_gateway_types.go | 65 +---- .../api/mesh/v2beta1/grpc_route_types_test.go | 2 +- .../api/mesh/v2beta1/http_route_types_test.go | 2 +- .../mesh/v2beta1/mesh_configuration_types.go | 5 +- .../api/mesh/v2beta1/mesh_gateway_types.go | 53 +--- .../v2beta1/proxy_configuration_types_test.go | 2 +- .../api/mesh/v2beta1/tcp_route_types_test.go | 2 +- .../api/mesh/v2beta1/zz_generated.deepcopy.go | 61 +---- .../v2/exported_services_types.go | 1 + .../build-support/functions/10-util.sh | 5 +- ...nsul.hashicorp.com_trafficpermissions.yaml | 72 +++--- ...mesh.consul.hashicorp.com_apigateways.yaml | 131 +++------- .../mesh.consul.hashicorp.com_grpcroutes.yaml | 23 +- .../mesh.consul.hashicorp.com_httproutes.yaml | 23 +- .../mesh.consul.hashicorp.com_tcproutes.yaml | 23 +- .../common/annotation_processor.go | 12 +- .../common/annotation_processor_test.go | 14 ++ .../endpointsv2/endpoints_controller.go | 4 +- .../controllers/pod/pod_controller.go | 2 +- .../controllers/pod/pod_controller_test.go | 6 +- .../resources/api-gateway-controller.go | 78 ------ .../resources/api-gateway-controller_test.go | 182 -------------- .../resources/gateway_controller_setup.go | 140 ----------- .../controllers/resources/gateway_indices.go | 75 ------ .../resources/mesh_gateway_controller.go | 99 +++++++- control-plane/gateways/builder.go | 23 +- control-plane/gateways/deployment.go | 14 +- .../deployment_dataplane_container.go | 21 +- .../gateways/deployment_init_container.go | 10 +- control-plane/gateways/deployment_test.go | 28 +-- control-plane/gateways/metadata.go | 44 ++-- control-plane/gateways/metadata_test.go | 13 +- control-plane/gateways/role.go | 16 +- control-plane/gateways/service.go | 44 +++- control-plane/gateways/service_test.go | 144 +---------- control-plane/gateways/serviceaccount.go | 8 +- control-plane/gateways/serviceaccount_test.go | 2 +- control-plane/go.mod | 2 +- control-plane/go.sum | 4 +- .../inject-connect/v2controllers.go | 15 -- .../subcommand/mesh-init/command_test.go | 14 +- control-plane/version/version.go | 2 +- 72 files changed, 546 insertions(+), 2191 deletions(-) delete mode 100644 .github/workflows/weekly-acceptance-1-4-0-rc1.yml delete mode 100644 .github/workflows/weekly-acceptance-1-4-x.yml delete mode 100644 acceptance/framework/resource/helpers.go delete mode 100644 acceptance/tests/api-gateway_v2/api_gateway_v2_test.go delete mode 100644 acceptance/tests/api-gateway_v2/helpers.go delete mode 100644 acceptance/tests/api-gateway_v2/main_test.go delete mode 100644 acceptance/tests/fixtures/bases/api-gateway-v2/apigateway.yaml delete mode 100644 acceptance/tests/fixtures/bases/api-gateway-v2/certificate.yaml delete mode 100644 acceptance/tests/fixtures/bases/api-gateway-v2/gatewayclass.yaml delete mode 100644 acceptance/tests/fixtures/bases/api-gateway-v2/gatewayclassconfig.yaml delete mode 100644 acceptance/tests/fixtures/bases/api-gateway-v2/kustomization.yaml delete mode 100644 acceptance/tests/fixtures/bases/api-gateway-v2/tcproute.yaml delete mode 100644 acceptance/tests/tenancy_v2/namespace_test.go delete mode 100644 control-plane/controllers/resources/api-gateway-controller.go delete mode 100644 control-plane/controllers/resources/api-gateway-controller_test.go delete mode 100644 control-plane/controllers/resources/gateway_controller_setup.go delete mode 100644 control-plane/controllers/resources/gateway_indices.go diff --git a/.github/workflows/weekly-acceptance-1-4-0-rc1.yml b/.github/workflows/weekly-acceptance-1-4-0-rc1.yml deleted file mode 100644 index e74a44ea70..0000000000 --- a/.github/workflows/weekly-acceptance-1-4-0-rc1.yml +++ /dev/null @@ -1,28 +0,0 @@ -# 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-4-0-rc1 -on: - schedule: - # * is a special character in YAML so you have to quote this string - # Run weekly on Friday at 3AM UTC/11PM EST/8PM PST - - cron: '0 3 * * 5' - -# these should be the only settings that you will ever need to change -env: - BRANCH: "release/1.4.0-rc1" - 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 }}" }' diff --git a/.github/workflows/weekly-acceptance-1-4-x.yml b/.github/workflows/weekly-acceptance-1-4-x.yml deleted file mode 100644 index a6bbe05e6b..0000000000 --- a/.github/workflows/weekly-acceptance-1-4-x.yml +++ /dev/null @@ -1,28 +0,0 @@ -# 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-4-x -on: - schedule: - # * is a special character in YAML so you have to quote this string - # Run weekly on Thursday at 3AM UTC/11PM EST/8PM PST - - cron: '0 3 * * 4' - -# these should be the only settings that you will ever need to change -env: - BRANCH: "release/1.4.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 }}" }' diff --git a/acceptance/framework/connhelper/connect_helper.go b/acceptance/framework/connhelper/connect_helper.go index 2746b43348..bbcaf7aff9 100644 --- a/acceptance/framework/connhelper/connect_helper.go +++ b/acceptance/framework/connhelper/connect_helper.go @@ -294,7 +294,7 @@ func (c *ConnectHelper) SetupAppNamespace(t *testing.T) { } // CreateResolverRedirect creates a resolver that redirects to a static-server, a corresponding k8s service, -// and intentions. This helper is primarily used to ensure that the virtual-ips are persisted to consul properly. +// 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") opts := c.KubectlOptsForApp(t) diff --git a/acceptance/framework/resource/helpers.go b/acceptance/framework/resource/helpers.go deleted file mode 100644 index 4e94f73faf..0000000000 --- a/acceptance/framework/resource/helpers.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resource - -import ( - "context" - "time" - - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/status" - - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/hashicorp/consul/sdk/testutil/retry" -) - -// ResourceTester is a helper for making assertions about resources. -type ResourceTester struct { - // resourceClient is the client to use for resource operations. - resourceClient pbresource.ResourceServiceClient - // timeout is the total time across which to apply retries. - timeout time.Duration - // wait is the wait time between retries. - wait time.Duration - // token is the token to use for requests when ACLs are enabled. - token string -} - -func NewResourceTester(resourceClient pbresource.ResourceServiceClient) *ResourceTester { - return &ResourceTester{ - resourceClient: resourceClient, - timeout: 7 * time.Second, - wait: 25 * time.Millisecond, - } -} - -func (rt *ResourceTester) retry(t testutil.TestingTB, fn func(r *retry.R)) { - t.Helper() - retryer := &retry.Timer{Timeout: rt.timeout, Wait: rt.wait} - retry.RunWith(retryer, t, fn) -} - -func (rt *ResourceTester) Context(t testutil.TestingTB) context.Context { - ctx := testutil.TestContext(t) - - if rt.token != "" { - md := metadata.New(map[string]string{ - "x-consul-token": rt.token, - }) - ctx = metadata.NewOutgoingContext(ctx, md) - } - - return ctx -} - -func (rt *ResourceTester) RequireResourceExists(t testutil.TestingTB, id *pbresource.ID) *pbresource.Resource { - t.Helper() - - rsp, err := rt.resourceClient.Read(rt.Context(t), &pbresource.ReadRequest{Id: id}) - require.NoError(t, err, "error reading %s with type %v", id.Name, id.Type) - require.NotNil(t, rsp) - return rsp.Resource -} - -func (rt *ResourceTester) RequireResourceNotFound(t testutil.TestingTB, id *pbresource.ID) { - t.Helper() - - rsp, err := rt.resourceClient.Read(rt.Context(t), &pbresource.ReadRequest{Id: id}) - require.Error(t, err) - require.Equal(t, codes.NotFound, status.Code(err)) - require.Nil(t, rsp) -} - -func (rt *ResourceTester) WaitForResourceExists(t testutil.TestingTB, id *pbresource.ID) *pbresource.Resource { - t.Helper() - - var res *pbresource.Resource - rt.retry(t, func(r *retry.R) { - res = rt.RequireResourceExists(r, id) - }) - - return res -} - -func (rt *ResourceTester) WaitForResourceNotFound(t testutil.TestingTB, id *pbresource.ID) { - t.Helper() - - rt.retry(t, func(r *retry.R) { - rt.RequireResourceNotFound(r, id) - }) -} diff --git a/acceptance/go.mod b/acceptance/go.mod index 7a8cc6de8c..8be66a29da 100644 --- a/acceptance/go.mod +++ b/acceptance/go.mod @@ -4,13 +4,13 @@ go 1.20 replace github.com/hashicorp/consul/sdk => github.com/hashicorp/consul/sdk v0.4.1-0.20231213150639-123bc95e1a3f -replace github.com/hashicorp/consul/proto-public => github.com/hashicorp/consul/proto-public v0.1.2-0.20240129174413-a2d50af1bdfb +replace github.com/hashicorp/consul/proto-public => github.com/hashicorp/consul/proto-public v0.1.2-0.20231212195019-69e3f93ee8a3 require ( github.com/google/uuid v1.3.0 github.com/gruntwork-io/terratest v0.31.2 - github.com/hashicorp/consul-k8s/control-plane v0.0.0-20240201210635-25708a18e4aa - github.com/hashicorp/consul/api v1.10.1-0.20240122152324-758ddf84e9c9 + github.com/hashicorp/consul-k8s/control-plane v0.0.0-20230609143603-198c4433d892 + github.com/hashicorp/consul/api v1.10.1-0.20230906155245-56917eb4c968 github.com/hashicorp/consul/proto-public v0.5.1 github.com/hashicorp/consul/sdk v0.15.0 github.com/hashicorp/go-multierror v1.1.1 @@ -47,7 +47,7 @@ require ( 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.15.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.4 // indirect @@ -94,7 +94,7 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // 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/colorstring v0.0.0-20190213212951-d06e56a500db // indirect diff --git a/acceptance/go.sum b/acceptance/go.sum index 5dab27228c..36713f97e1 100644 --- a/acceptance/go.sum +++ b/acceptance/go.sum @@ -106,10 +106,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/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/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/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -184,8 +182,8 @@ github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl 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/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +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= @@ -393,13 +391,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-20240201210635-25708a18e4aa h1:T9u/mKHEqqQvv8jJ3+S4cLj9sn7KDMSW+n4Uc8YlVos= -github.com/hashicorp/consul-k8s/control-plane v0.0.0-20240201210635-25708a18e4aa/go.mod h1:Yj8VIjM3SElLcOVTkjy/A0igua8XBuhteYuQ1O84FDY= -github.com/hashicorp/consul-server-connection-manager v0.1.6 h1:ktj8Fi+dRXn9hhM+FXsfEJayhzzgTqfH08Ne5M6Fmug= -github.com/hashicorp/consul/api v1.10.1-0.20240122152324-758ddf84e9c9 h1:qaS6rE768dt5hGPl2y4DIABXF4eA23BNSmWFpEr3kWQ= -github.com/hashicorp/consul/api v1.10.1-0.20240122152324-758ddf84e9c9/go.mod h1:gInwZGrnWlE1Vvq6rSD5pUf6qwNa69NTLLknbdwQRUk= -github.com/hashicorp/consul/proto-public v0.1.2-0.20240129174413-a2d50af1bdfb h1:4LCdNw3DTe5WRe3fJvY+hkRLNtRlunl/9PJuOlQmPa8= -github.com/hashicorp/consul/proto-public v0.1.2-0.20240129174413-a2d50af1bdfb/go.mod h1:ar/M/Gv31GeE7DxektZgAydwsCiOf6sBeJFcjQVTlVs= +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.10.1-0.20230906155245-56917eb4c968 h1:lQ7QmlL0N4/ftLBex8n73Raji29o7EVssqCoeeczKac= +github.com/hashicorp/consul/api v1.10.1-0.20230906155245-56917eb4c968/go.mod h1:NZJGRFYruc/80wYowkPFCp1LbGmJC9L8izrwfyVx/Wg= +github.com/hashicorp/consul/proto-public v0.1.2-0.20231212195019-69e3f93ee8a3 h1:FFRKi+IpoXHwXZDgqG+BNAG1duAuokbzm+5b2pcY1us= +github.com/hashicorp/consul/proto-public v0.1.2-0.20231212195019-69e3f93ee8a3/go.mod h1:fCFq3EfW2Iwu5her/hgqVqcJikY8nBtDiKFgfOdBvvw= github.com/hashicorp/consul/sdk v0.4.1-0.20231213150639-123bc95e1a3f h1:GKsa7bfoL7xgvCkzYJMF9eYYNfLWQyk8QuRZZl4nMTo= github.com/hashicorp/consul/sdk v0.4.1-0.20231213150639-123bc95e1a3f/go.mod h1:r/OmRRPbHOe0yxNahLw7G9x5WG17E1BIECMtCjcPSNo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -423,7 +420,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-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= @@ -547,8 +543,8 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA 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/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +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= @@ -983,7 +979,6 @@ 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.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/acceptance/tests/api-gateway_v2/api_gateway_v2_test.go b/acceptance/tests/api-gateway_v2/api_gateway_v2_test.go deleted file mode 100644 index 1e01584e32..0000000000 --- a/acceptance/tests/api-gateway_v2/api_gateway_v2_test.go +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package apigatewayv2 - -import ( - "context" - "encoding/base64" - "fmt" - "strconv" - "testing" - "time" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - - "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" - meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" - - "github.com/stretchr/testify/require" - "k8s.io/apimachinery/pkg/types" -) - -// Test that api gateway basic functionality works in a default installation and a secure installation for V2. -func TestAPIGateway_V2_Basic(t *testing.T) { - - cases := []struct { - secure bool - }{ - { - secure: false, - }, - { - secure: true, - }, - } - for _, c := range cases { - name := fmt.Sprintf("secure: %t", c.secure) - t.Run(name, func(t *testing.T) { - ctx := suite.Environment().DefaultContext(t) - cfg := suite.Config() - helmValues := map[string]string{ - "connectInject.enabled": "true", - "global.acls.manageSystemACLs": strconv.FormatBool(c.secure), - "global.tls.enabled": strconv.FormatBool(c.secure), - "global.logLevel": "trace", - "global.experiments[0]": "resource-apis", - } - - 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, c.secure) - _, _, 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/bases/api-gateway-v2") - 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/bases/api-gateway-v2") - }) - - // 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-v2/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-v2/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") - - logger.Log(t, "creating target tcp server") - 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-v2/tcproute/route.yaml") - 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-v2/tcproute/route.yaml") - }) - - // 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 timeout here). - var gatewayAddress string - counter := &retry.Counter{Count: 120, Wait: 2 * time.Second} - retry.RunWith(counter, t, func(r *retry.R) { - var gateway meshv2beta1.APIGateway - 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 - checkV2StatusCondition(r, gateway.APIGatewayStatus.Conditions, trueV2Condition("Accepted", "Accepted")) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Conditions, trueV2Condition("ConsulAccepted", "Accepted")) - require.Len(r, gateway.APIGatewayStatus.Listeners, 3) - - require.EqualValues(r, 1, gateway.APIGatewayStatus.Listeners[0].AttachedRoutes) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[0].Conditions, trueV2Condition("Accepted", "Accepted")) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[0].Conditions, falseV2Condition("Conflicted", "NoConflicts")) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[0].Conditions, trueV2Condition("ResolvedRefs", "ResolvedRefs")) - require.EqualValues(r, 1, gateway.APIGatewayStatus.Listeners[1].AttachedRoutes) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[1].Conditions, trueV2Condition("Accepted", "Accepted")) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[1].Conditions, falseV2Condition("Conflicted", "NoConflicts")) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[1].Conditions, trueV2Condition("ResolvedRefs", "ResolvedRefs")) - require.EqualValues(r, 1, gateway.APIGatewayStatus.Listeners[2].AttachedRoutes) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[2].Conditions, trueV2Condition("Accepted", "Accepted")) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[2].Conditions, falseV2Condition("Conflicted", "NoConflicts")) - checkV2StatusCondition(r, gateway.APIGatewayStatus.Listeners[2].Conditions, trueV2Condition("ResolvedRefs", "ResolvedRefs")) - - // check that we have an address to use - require.Len(r, gateway.APIGatewayStatus.Addresses, 1) - // now we know we have an address, set it so we can use it - gatewayAddress = gateway.APIGatewayStatus.Addresses[0].Value - }) - - // now that we've satisfied those assertions, we know reconciliation is done - // so we can run assertions on the routes and the other objects - - // gateway class checks - var gatewayClass meshv2beta1.GatewayClass - err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "gateway-class"}, &gatewayClass) - require.NoError(t, err) - - // check our finalizers - require.Len(t, gatewayClass.Finalizers, 1) - require.EqualValues(t, gatewayClassFinalizer, gatewayClass.Finalizers()[0]) - - // tcp route checks - var tcpRoute meshv2beta1.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]) - - // TODO check values actually created in the resource API - - // finally we check that we can actually route to the service via the gateway - k8sOptions := ctx.KubectlOptions(t) - targetTCPAddress := fmt.Sprintf("http://%s:81", gatewayAddress) - - // 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 tcp") - k8s.CheckStaticServerConnectionSuccessful(t, k8sOptions, StaticClientName, targetTCPAddress) - - }) - } -} diff --git a/acceptance/tests/api-gateway_v2/helpers.go b/acceptance/tests/api-gateway_v2/helpers.go deleted file mode 100644 index 124fa20450..0000000000 --- a/acceptance/tests/api-gateway_v2/helpers.go +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package apigatewayv2 - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/x509" - "crypto/x509/pkix" - "encoding/pem" - meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" - corev1 "k8s.io/api/core/v1" - "math/big" - "testing" - "time" - - "github.com/stretchr/testify/require" -) - -const ( - StaticClientName = "static-client" - gatewayClassControllerName = "mesh.consul.hashicorp.com/gateway-controller" - //TODO these values will likely need to be update to their V2 values for the test to pass. - gatewayClassFinalizer = "gateway-exists-finalizer.consul.hashicorp.com" - gatewayFinalizer = "gateway-finalizer.consul.hashicorp.com" -) - -type certificateInfo struct { - Cert *x509.Certificate - PrivateKey *rsa.PrivateKey - CertPEM []byte - PrivateKeyPEM []byte -} - -func checkV2StatusCondition(t require.TestingT, conditions []meshv2beta1.Condition, toCheck meshv2beta1.Condition) { - for _, c := range conditions { - if c.Type == toCheck.Type { - require.EqualValues(t, toCheck.Reason, c.Reason) - require.EqualValues(t, toCheck.Status, c.Status) - return - } - } - - t.Errorf("expected condition not found: %s", toCheck.Type) -} - -func trueV2Condition(conditionType, reason string) meshv2beta1.Condition { - return meshv2beta1.Condition{ - Type: meshv2beta1.ConditionType(conditionType), - Reason: reason, - Status: corev1.ConditionTrue, - } -} - -func falseV2Condition(conditionType, reason string) meshv2beta1.Condition { - return meshv2beta1.Condition{ - Type: meshv2beta1.ConditionType(conditionType), - Reason: reason, - Status: corev1.ConditionFalse, - } -} - -func generateCertificate(t *testing.T, ca *certificateInfo, commonName string) *certificateInfo { - t.Helper() - - bits := 2048 - privateKey, err := rsa.GenerateKey(rand.Reader, bits) - require.NoError(t, err) - - usage := x509.KeyUsageDigitalSignature - if ca == nil { - usage = x509.KeyUsageCertSign - } - - expiration := time.Now().AddDate(10, 0, 0) - cert := &x509.Certificate{ - SerialNumber: big.NewInt(1), - Subject: pkix.Name{ - Organization: []string{"Testing, INC."}, - Country: []string{"US"}, - Province: []string{""}, - Locality: []string{"San Francisco"}, - StreetAddress: []string{"Fake Street"}, - PostalCode: []string{"11111"}, - CommonName: commonName, - }, - IsCA: ca == nil, - 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 - if ca != nil { - caCert = ca.Cert - } - caPrivateKey := privateKey - if ca != nil { - caPrivateKey = ca.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), - }) - - return &certificateInfo{ - Cert: cert, - CertPEM: certBytes, - PrivateKey: privateKey, - PrivateKeyPEM: privateKeyBytes, - } -} diff --git a/acceptance/tests/api-gateway_v2/main_test.go b/acceptance/tests/api-gateway_v2/main_test.go deleted file mode 100644 index 47f4c3b3cf..0000000000 --- a/acceptance/tests/api-gateway_v2/main_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package apigatewayv2 - -import ( - "fmt" - "os" - "testing" - - testsuite "github.com/hashicorp/consul-k8s/acceptance/framework/suite" -) - -var suite testsuite.Suite - -func TestMain(m *testing.M) { - runTests := os.Getenv("TEST_APIGW_V2") - if runTests != "TRUE" { - fmt.Println("skipping") - os.Exit(0) - } - suite = testsuite.NewSuite(m) - os.Exit(suite.Run()) -} diff --git a/acceptance/tests/fixtures/bases/api-gateway-v2/apigateway.yaml b/acceptance/tests/fixtures/bases/api-gateway-v2/apigateway.yaml deleted file mode 100644 index c4fa0d6364..0000000000 --- a/acceptance/tests/fixtures/bases/api-gateway-v2/apigateway.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: APIGateway -metadata: - name: gateway -spec: - gatewayClassName: gateway-class - listeners: - - protocol: TCP - port: 81 - name: tcp - allowedRoutes: - namespaces: - from: "All" diff --git a/acceptance/tests/fixtures/bases/api-gateway-v2/certificate.yaml b/acceptance/tests/fixtures/bases/api-gateway-v2/certificate.yaml deleted file mode 100644 index d35dc559e2..0000000000 --- a/acceptance/tests/fixtures/bases/api-gateway-v2/certificate.yaml +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: v1 -kind: Secret -metadata: - name: certificate -type: kubernetes.io/tls -data: - tls.crt: "" - tls.key: "" \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/api-gateway-v2/gatewayclass.yaml b/acceptance/tests/fixtures/bases/api-gateway-v2/gatewayclass.yaml deleted file mode 100644 index 583ffc210a..0000000000 --- a/acceptance/tests/fixtures/bases/api-gateway-v2/gatewayclass.yaml +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: GatewayClass -metadata: - name: gateway-class -spec: - controllerName: "consul.hashicorp.com/gateway-controller" - parametersRef: - group: consul.hashicorp.com - kind: GatewayClassConfig - name: gateway-class-config diff --git a/acceptance/tests/fixtures/bases/api-gateway-v2/gatewayclassconfig.yaml b/acceptance/tests/fixtures/bases/api-gateway-v2/gatewayclassconfig.yaml deleted file mode 100644 index 049cdd708f..0000000000 --- a/acceptance/tests/fixtures/bases/api-gateway-v2/gatewayclassconfig.yaml +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: GatewayClassConfig -metadata: - name: gateway-class-config \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/api-gateway-v2/kustomization.yaml b/acceptance/tests/fixtures/bases/api-gateway-v2/kustomization.yaml deleted file mode 100644 index 871949a1ab..0000000000 --- a/acceptance/tests/fixtures/bases/api-gateway-v2/kustomization.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -resources: - - gatewayclassconfig.yaml - - gatewayclass.yaml - - apigateway.yaml - - tcproute.yaml \ No newline at end of file diff --git a/acceptance/tests/fixtures/bases/api-gateway-v2/tcproute.yaml b/acceptance/tests/fixtures/bases/api-gateway-v2/tcproute.yaml deleted file mode 100644 index c06b0e4ee0..0000000000 --- a/acceptance/tests/fixtures/bases/api-gateway-v2/tcproute.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -apiVersion: mesh.consul.hashicorp.com/v2beta1 -kind: TCPRoute -metadata: - name: tcp-route -spec: - parentRefs: - - name: gateway \ No newline at end of file diff --git a/acceptance/tests/mesh_v2/mesh_inject_test.go b/acceptance/tests/mesh_v2/mesh_inject_test.go index e44a2296af..d54229d84b 100644 --- a/acceptance/tests/mesh_v2/mesh_inject_test.go +++ b/acceptance/tests/mesh_v2/mesh_inject_test.go @@ -37,6 +37,7 @@ func TestMeshInject_MultiportService(t *testing.T) { helmValues := map[string]string{ "global.experiments[0]": "resource-apis", + "global.image": "ndhanushkodi/consul-dev:expose2", // The UI is not supported for v2 in 1.17, so for now it must be disabled. "ui.enabled": "false", "connectInject.enabled": "true", diff --git a/acceptance/tests/tenancy_v2/namespace_test.go b/acceptance/tests/tenancy_v2/namespace_test.go deleted file mode 100644 index cb19565472..0000000000 --- a/acceptance/tests/tenancy_v2/namespace_test.go +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package tenancy_v2 - -import ( - "testing" - - "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-k8s/acceptance/framework/resource" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" -) - -// TestTenancy_Namespace_Mirrored tests consul namespaces are created/deleted -// to mirror k8s namespaces in the default partition. -func TestTenancy_Namespace_Mirrored(t *testing.T) { - cfg := suite.Config() - cfg.SkipWhenCNI(t) - ctx := suite.Environment().DefaultContext(t) - - serverHelmValues := map[string]string{ - "server.enabled": "true", - "global.experiments[0]": "resource-apis", - "global.experiments[1]": "v2tenancy", - // The UI is not supported for v2 in 1.17, so for now it must be disabled. - "ui.enabled": "false", - } - - serverReleaseName := helpers.RandomName() - serverCluster := consul.NewHelmCluster(t, serverHelmValues, ctx, cfg, serverReleaseName) - serverCluster.Create(t) - - logger.Log(t, "creating namespace ns1 in k8s") - k8s.RunKubectl(t, ctx.KubectlOptions(t), "create", "namespace", "ns1") - - logger.Log(t, "waiting for namespace ns1 to be created in consul") - serverResourceClient := serverCluster.ResourceClient(t, false) - rtest := resource.NewResourceTester(serverResourceClient) - rtest.WaitForResourceExists(t, &pbresource.ID{ - Name: "ns1", - Type: pbtenancy.NamespaceType, - Tenancy: &pbresource.Tenancy{ - Partition: "default", - }, - }) - - logger.Log(t, "deleting namespace ns1 in k8s") - k8s.RunKubectl(t, ctx.KubectlOptions(t), "delete", "namespace", "ns1") - - logger.Log(t, "waiting for namespace ns1 to be deleted in consul") - rtest.WaitForResourceNotFound(t, &pbresource.ID{ - Name: "ns1", - Type: pbtenancy.NamespaceType, - Tenancy: &pbresource.Tenancy{ - Partition: "default", - }, - }) -} diff --git a/charts/consul/Chart.yaml b/charts/consul/Chart.yaml index d74a42ba95..c33e0f4dac 100644 --- a/charts/consul/Chart.yaml +++ b/charts/consul/Chart.yaml @@ -3,8 +3,8 @@ apiVersion: v2 name: consul -version: 1.5.0-dev -appVersion: 1.19-dev +version: 1.4.0-dev +appVersion: 1.18-dev kubeVersion: ">=1.22.0-0" description: Official HashiCorp Consul Chart home: https://www.consul.io @@ -16,11 +16,11 @@ annotations: artifacthub.io/prerelease: true artifacthub.io/images: | - name: consul - image: docker.mirror.hashicorp.services/hashicorppreview/consul:1.19-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul:1.18-dev - name: consul-k8s-control-plane - image: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.5-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.4-dev - name: consul-dataplane - image: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.5-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.4-dev - name: envoy image: envoyproxy/envoy:v1.25.11 artifacthub.io/license: MPL-2.0 diff --git a/charts/consul/templates/connect-inject-clusterrole.yaml b/charts/consul/templates/connect-inject-clusterrole.yaml index be816ff391..c6845870ba 100644 --- a/charts/consul/templates/connect-inject-clusterrole.yaml +++ b/charts/consul/templates/connect-inject-clusterrole.yaml @@ -102,7 +102,6 @@ rules: - grpcroutes - httproutes - meshgateways - - apigateways - tcproutes - proxyconfigurations verbs: @@ -122,7 +121,6 @@ rules: - grpcroutes/status - httproutes/status - meshgateways/status - - apigateways/status - tcproutes/status - proxyconfigurations/status verbs: diff --git a/charts/consul/templates/crd-apigateways.yaml b/charts/consul/templates/crd-apigateways.yaml index cca95dae89..755fb05b64 100644 --- a/charts/consul/templates/crd-apigateways.yaml +++ b/charts/consul/templates/crd-apigateways.yaml @@ -114,6 +114,13 @@ spec: provide the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer the + resource is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, + provide the wildcard value \"*\" to list resources + across all peers." + type: string type: object type: description: Type identifies the resource's type. @@ -189,113 +196,41 @@ spec: type: object status: properties: - addresses: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. items: + description: 'Conditions define a readiness condition for a Consul + resource. See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties' properties: - type: - default: IPAddress + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time type: string - value: + message: + description: A human readable message indicating details about + the transition. type: string - required: - - type - - value - type: object - type: array - listeners: - items: - properties: - attachedRoutes: - format: int32 - type: integer - name: + reason: + description: The reason for the condition's last transition. type: string status: - properties: - conditions: - description: Conditions indicate the latest available observations - of a resource's current state. - items: - description: 'Conditions define a readiness condition - for a Consul resource. See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties' - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the - condition transitioned from one status to another. - format: date-time - type: string - message: - description: A human readable message indicating details - about the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, - False, Unknown. - type: string - type: - description: Type of condition. - type: string - required: - - status - - type - type: object - type: array - lastSyncedTime: - description: LastSyncedTime is the last time the resource - successfully synced with Consul. - format: date-time - type: string - type: object + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition. + type: string required: - - attachedRoutes - - name + - status + - type type: object type: array - status: - properties: - conditions: - description: Conditions indicate the latest available observations - of a resource's current state. - items: - description: 'Conditions define a readiness condition for a - Consul resource. See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties' - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: A human readable message indicating details - about the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - type: string - type: - description: Type of condition. - type: string - required: - - status - - type - type: object - type: array - lastSyncedTime: - description: LastSyncedTime is the last time the resource successfully - synced with Consul. - format: date-time - type: string - type: object - required: - - addresses - - listeners + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string type: object type: object served: true diff --git a/charts/consul/templates/crd-grpcroutes.yaml b/charts/consul/templates/crd-grpcroutes.yaml index 8766c8edbe..31812fff35 100644 --- a/charts/consul/templates/crd-grpcroutes.yaml +++ b/charts/consul/templates/crd-grpcroutes.yaml @@ -72,10 +72,9 @@ spec: description: 'NOTE: roughly equivalent to structs.ResourceReference' properties: port: - description: "For east/west this is the name of the Consul Service + description: For east/west this is the name of the Consul Service port to direct traffic to or empty to imply all. For north/south - this is TBD. \n For more details on potential values of this - field, see documentation for Service.ServicePort." + this is TBD. type: string ref: description: For east/west configuration, this should point @@ -107,6 +106,13 @@ spec: the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer the resource + is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, provide + the wildcard value \"*\" to list resources across + all peers." + type: string type: object type: description: Type identifies the resource's type. @@ -160,9 +166,7 @@ spec: description: "For east/west this is the name of the Consul Service port to direct traffic to or empty to imply using the same value as the parent ref. - For north/south this is TBD. \n For more details - on potential values of this field, see documentation - for Service.ServicePort." + \n For north/south this is TBD." type: string ref: description: For east/west configuration, this should @@ -195,6 +199,13 @@ spec: provide the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer + the resource is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, + provide the wildcard value \"*\" to list + resources across all peers." + type: string type: object type: description: Type identifies the resource's type. diff --git a/charts/consul/templates/crd-httproutes.yaml b/charts/consul/templates/crd-httproutes.yaml index c829bf1fc3..3da6e1e637 100644 --- a/charts/consul/templates/crd-httproutes.yaml +++ b/charts/consul/templates/crd-httproutes.yaml @@ -72,10 +72,9 @@ spec: description: 'NOTE: roughly equivalent to structs.ResourceReference' properties: port: - description: "For east/west this is the name of the Consul Service + description: For east/west this is the name of the Consul Service port to direct traffic to or empty to imply all. For north/south - this is TBD. \n For more details on potential values of this - field, see documentation for Service.ServicePort." + this is TBD. type: string ref: description: For east/west configuration, this should point @@ -107,6 +106,13 @@ spec: the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer the resource + is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, provide + the wildcard value \"*\" to list resources across + all peers." + type: string type: object type: description: Type identifies the resource's type. @@ -163,9 +169,7 @@ spec: description: "For east/west this is the name of the Consul Service port to direct traffic to or empty to imply using the same value as the parent ref. - For north/south this is TBD. \n For more details - on potential values of this field, see documentation - for Service.ServicePort." + \n For north/south this is TBD." type: string ref: description: For east/west configuration, this should @@ -198,6 +202,13 @@ spec: provide the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer + the resource is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, + provide the wildcard value \"*\" to list + resources across all peers." + type: string type: object type: description: Type identifies the resource's type. diff --git a/charts/consul/templates/crd-tcproutes.yaml b/charts/consul/templates/crd-tcproutes.yaml index c0e87a9c3c..ae9d2cd080 100644 --- a/charts/consul/templates/crd-tcproutes.yaml +++ b/charts/consul/templates/crd-tcproutes.yaml @@ -66,10 +66,9 @@ spec: description: 'NOTE: roughly equivalent to structs.ResourceReference' properties: port: - description: "For east/west this is the name of the Consul Service + description: For east/west this is the name of the Consul Service port to direct traffic to or empty to imply all. For north/south - this is TBD. \n For more details on potential values of this - field, see documentation for Service.ServicePort." + this is TBD. type: string ref: description: For east/west configuration, this should point @@ -101,6 +100,13 @@ spec: the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer the resource + is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, provide + the wildcard value \"*\" to list resources across + all peers." + type: string type: object type: description: Type identifies the resource's type. @@ -145,9 +151,7 @@ spec: description: "For east/west this is the name of the Consul Service port to direct traffic to or empty to imply using the same value as the parent ref. - For north/south this is TBD. \n For more details - on potential values of this field, see documentation - for Service.ServicePort." + \n For north/south this is TBD." type: string ref: description: For east/west configuration, this should @@ -180,6 +184,13 @@ spec: provide the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer + the resource is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, + provide the wildcard value \"*\" to list + resources across all peers." + type: string type: object type: description: Type identifies the resource's type. diff --git a/charts/consul/templates/crd-trafficpermissions.yaml b/charts/consul/templates/crd-trafficpermissions.yaml index 87727f4fbf..27ab6f5e3d 100644 --- a/charts/consul/templates/crd-trafficpermissions.yaml +++ b/charts/consul/templates/crd-trafficpermissions.yaml @@ -101,25 +101,23 @@ spec: when evaluating rules for the incoming connection. items: properties: - headers: - items: - properties: - exact: - type: string - invert: - type: boolean - name: - type: string - prefix: - type: string - present: - type: boolean - regex: - type: string - suffix: - type: string - type: object - type: array + header: + properties: + exact: + type: string + invert: + type: boolean + name: + type: string + prefix: + type: string + present: + type: boolean + regex: + type: string + suffix: + type: string + type: object methods: description: Methods is the list of HTTP methods. items: @@ -140,25 +138,23 @@ spec: type: array type: object type: array - headers: - items: - properties: - exact: - type: string - invert: - type: boolean - name: - type: string - prefix: - type: string - present: - type: boolean - regex: - type: string - suffix: - type: string - type: object - type: array + header: + properties: + exact: + type: string + invert: + type: boolean + name: + type: string + prefix: + type: string + present: + type: boolean + regex: + type: string + suffix: + type: string + type: object methods: description: Methods is the list of HTTP methods. If no methods are specified, this rule will apply to all methods. diff --git a/charts/consul/templates/gateway-resources-configmap.yaml b/charts/consul/templates/gateway-resources-configmap.yaml index d00f9b3e86..842ba6690d 100644 --- a/charts/consul/templates/gateway-resources-configmap.yaml +++ b/charts/consul/templates/gateway-resources-configmap.yaml @@ -21,10 +21,9 @@ data: resources.json: | {{ toJson .Values.connectInject.apiGateway.managedGatewayClass.resources }} {{- end }} - {{- if and (mustHas "resource-apis" .Values.global.experiments) (or .Values.meshGateway.enabled .Values.connectInject.apiGateway.managedGatewayClass) }} + {{- if and (mustHas "resource-apis" .Values.global.experiments) .Values.meshGateway.enabled }} config.yaml: | gatewayClassConfigs: - {{- if .Values.meshGateway.enabled }} - apiVersion: mesh.consul.hashicorp.com/v2beta1 metadata: name: consul-mesh-gateway @@ -88,8 +87,7 @@ data: min: {{ .Values.meshGateway.replicas }} max: {{ .Values.meshGateway.replicas }} {{- if .Values.meshGateway.tolerations }} - tolerations: - {{ fromYamlArray .Values.meshGateway.tolerations | toJson }} + tolerations: {{ fromYamlArray .Values.meshGateway.tolerations | toJson }} {{- end }} service: {{- if .Values.meshGateway.service.annotations }} @@ -102,67 +100,6 @@ data: annotations: set: {{ toJson .Values.meshGateway.serviceAccount.annotations }} {{- end }} - {{- end }} - {{- if .Values.connectInject.apiGateway.managedGatewayClass }} - - apiVersion: mesh.consul.hashicorp.com/v2beta1 - metadata: - name: consul-api-gateway - kind: GatewayClassConfig - spec: - labels: - set: - app: {{ template "consul.name" . }} - chart: {{ template "consul.chart" . }} - heritage: {{ .Release.Service }} - release: {{ .Release.Name }} - component: api-gateway - {{- if .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations }} - {{- if .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service }} - annotations: - service: - {{ fromYamlArray .Values.connectInject.apiGateway.managedGatewayClass.copyAnnotations.service.annotations | toYaml }} - {{- end}} - {{- end}} - deployment: - {{- if .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector }} - nodeSelector: - {{ fromYamlArray .Values.connectInject.apiGateway.managedGatewayClass.nodeSelector | toYaml }} - {{- end }} - initContainer: - {{- if .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} - portModifier: {{ .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} - {{- end }} - consul: - logging: - level: {{ .Values.global.logLevel }} - container: - {{- if .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} - portModifier: {{ .Values.connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts }} - {{- end }} - consul: - logging: - level: {{ .Values.global.logLevel }} - replicas: - default: {{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.defaultInstances }} - min: {{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.minInstances }} - max: {{ .Values.connectInject.apiGateway.managedGatewayClass.deployment.maxInstances }} - {{- if .Values.connectInject.apiGateway.managedGatewayClass.tolerations }} - tolerations: - {{ fromYamlArray .Values.connectInject.apiGateway.managedGatewayClass.tolerations | toYaml }} - {{- end }} - {{- if .Values.connectInject.apiGateway.managedGatewayClass.service }} - service: - annotations: - set: {{ toYaml .Values.connectInject.apiGateway.managedGatewayClass.service.annotations }} - {{- end }} - type: {{ .Values.connectInject.apiGateway.managedGatewayClass.serviceType }} - {{- if .Values.connectInject.apiGateway.managedGatewayClass.serviceAccount }} - serviceAccount: - annotations: - set: {{ toYaml .Values.connectInject.apiGateway.managedGatewayClass.serviceAccount.annotations }} - {{- end }} - {{- end }} - {{- if .Values.meshGateway.enabled }} meshGateways: - apiVersion: mesh.consul.hashicorp.com/v2beta1 kind: MeshGateway @@ -170,6 +107,7 @@ data: name: mesh-gateway namespace: {{ .Release.Namespace }} annotations: + # TODO are these annotations even necessary? "consul.hashicorp.com/gateway-wan-address-source": {{ .Values.meshGateway.wanAddress.source | quote }} "consul.hashicorp.com/gateway-wan-address-static": {{ .Values.meshGateway.wanAddress.static | quote }} {{- if eq .Values.meshGateway.wanAddress.source "Service" }} @@ -190,6 +128,5 @@ data: workloads: prefixes: - "mesh-gateway" - {{- end }} {{- end }} {{- end }} diff --git a/charts/consul/test/unit/gateway-resources-configmap.bats b/charts/consul/test/unit/gateway-resources-configmap.bats index ea3decc5c7..e827644792 100644 --- a/charts/consul/test/unit/gateway-resources-configmap.bats +++ b/charts/consul/test/unit/gateway-resources-configmap.bats @@ -94,28 +94,6 @@ target=templates/gateway-resources-configmap.yaml } -#-------------------------------------------------------------------- -# API Gateway logLevel configuration - -@test "gateway-resources/ConfigMap: API Gateway logLevel default configuration" { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'meshGateway.enabled=false' \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.container.consul.logging.level') - [ "${actual}" = 'info' ] - - local actual=$(echo "$config" | yq -r '.initContainer.consul.logging.level') - [ "${actual}" = 'info' ] -} - - - @test "gateway-resources/ConfigMap: Mesh Gateway logLevel custom global configuration" { cd `chart_dir` local config=$(helm template \ @@ -221,17 +199,16 @@ target=templates/gateway-resources-configmap.yaml . | tee /dev/stderr | yq -r '.data["config.yaml"]' | yq -r '.meshGateways[0].metadata.annotations' | tee /dev/stderr) - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-address-source"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-address-source"]') [ "${actual}" = 'Service' ] - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-port"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-port"]') [ "${actual}" = '443' ] - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-address-static"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-address-static"]') [ "${actual}" = '' ] } - @test "gateway-resources/ConfigMap: Mesh Gateway WAN Address NodePort annotations" { cd `chart_dir` local annotations=$(helm template \ @@ -246,13 +223,13 @@ target=templates/gateway-resources-configmap.yaml . | tee /dev/stderr | yq -r '.data["config.yaml"]' | yq -r '.meshGateways[0].metadata.annotations' | tee /dev/stderr) - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-address-source"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-address-source"]') [ "${actual}" = 'Service' ] - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-port"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-port"]') [ "${actual}" = '30000' ] - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-address-static"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-address-static"]') [ "${actual}" = '' ] } @@ -269,209 +246,13 @@ target=templates/gateway-resources-configmap.yaml . | tee /dev/stderr | yq -r '.data["config.yaml"]' | yq -r '.meshGateways[0].metadata.annotations' | tee /dev/stderr) - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-address-source"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-address-source"]') [ "${actual}" = 'Static' ] - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-port"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-port"]') [ "${actual}" = '443' ] - local actual=$(echo "$annotations" | yq -r '.["consul.hashicorp.com/gateway-wan-address-static"]') + local actual=$(echo "$annotations" | jq -r '.["consul.hashicorp.com/gateway-wan-address-static"]') [ "${actual}" = '127.0.0.1' ] } -#-------------------------------------------------------------------- -# API Gateway Tests mapPrivilageContainerPorts - -@test "gateway-resources/ConfigMap: API Gateway mapPrivilageContainerPorts empty by default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.container.portModifier') - - [ "${actual}" = 'null' ] - - local actual=$(echo "$config" | yq -r '.initContainer.portModifier') - - [ "${actual}" = 'null' ] -} - - -@test "gateway-resources/ConfigMap: API Gateway mapPrivilageContainerPorts overrides default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - --set 'connectInject.apiGateway.managedGatewayClass.mapPrivilegedContainerPorts=80' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.container.portModifier') - - [ "${actual}" = '80' ] - - local actual=$(echo "$config" | yq -r '.initContainer.portModifier') - - [ "${actual}" = '80' ] -} - -#-------------------------------------------------------------------- -# API Gateway Tests deployment replicas - -@test "gateway-resources/ConfigMap: API Gateway deploymentConfig overrides default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - --set 'connectInject.apiGateway.managedGatewayClass.deployment.defaultInstances=2' \ - --set 'connectInject.apiGateway.managedGatewayClass.deployment.maxInstances=3' \ - --set 'connectInject.apiGateway.managedGatewayClass.deployment.minInstances=1' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.replicas.default') - [ "${actual}" = '2' ] - - local actual=$(echo "$config" | yq -r '.replicas.min') - [ "${actual}" = '1' ] - - local actual=$(echo "$config" | yq -r '.replicas.max') - [ "${actual}" = '3' ] -} - -@test "gateway-resources/ConfigMap: API Gateway deploymentConfig default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.replicas.default') - [ "${actual}" = '1' ] - - local actual=$(echo "$config" | yq -r '.replicas.min') - [ "${actual}" = '1' ] - - local actual=$(echo "$config" | yq -r '.replicas.max') - [ "${actual}" = '1' ] -} - -#-------------------------------------------------------------------- -# API Gateway Tests nodeSelector - -@test "gateway-resources/ConfigMap: API Gateway nodeSelector overrides default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - --set 'connectInject.apiGateway.managedGatewayClass.nodeSelector=- key: value' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.nodeSelector[0].key') - echo ${actual} - - [ "${actual}" = 'value' ] -} - -@test "gateway-resources/ConfigMap: API Gateway nodeSelector default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.nodeSelector') - [ "${actual}" = 'null' ] -} - -#-------------------------------------------------------------------- -# API Gateway Tests tolerations - -@test "gateway-resources/ConfigMap: API Gateway tolerations overrides default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - --set 'connectInject.apiGateway.managedGatewayClass.tolerations=- key: value' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.tolerations[0].key') - echo "${actual}" - - [ "${actual}" = 'value' ] -} - - - -@test "gateway-resources/ConfigMap: API Gateway tolerations default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.deployment' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.tolerations') - [ "${actual}" = 'null' ] -} - - -#-------------------------------------------------------------------- -# API Gateway Tests copyAnnotations - -@test "gateway-resources/ConfigMap: API Gateway copyAnnotations overrides default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - --set 'connectInject.apiGateway.managedGatewayClass.copyAnnotations.service.annotations=- annotation.name' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.annotations' | tee /dev/stderr) - - local actual=$(echo "$config" | yq -r '.service[0]') - echo "${actual}" - [ "${actual}" = 'annotation.name' ] -} - -@test "gateway-resources/ConfigMap: API Gateway copyAnnotations default { - cd `chart_dir` - local config=$(helm template \ - -s $target \ - --set 'global.experiments[0]=resource-apis' \ - --set 'ui.enabled=false' \ - --set 'global.logLevel=error' \ - . | tee /dev/stderr | - yq -r '.data["config.yaml"]' | yq -r '.gatewayClassConfigs[0].spec.annotations' | tee /dev/stderr) - - local actual=$(echo "$config" | jq -r '.service') - [ "${actual}" = 'null' ] -} - - -#-------------------------------------------------------------------- -# TODO openShiftSSCName \ No newline at end of file diff --git a/charts/consul/values.yaml b/charts/consul/values.yaml index fc3d886669..bc661f07b2 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.19-dev + image: docker.mirror.hashicorp.services/hashicorppreview/consul:1.18-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.5-dev + imageK8S: docker.mirror.hashicorp.services/hashicorppreview/consul-k8s-control-plane:1.4-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 @@ -791,7 +791,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.5-dev + imageConsulDataplane: docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.4-dev # Configuration for running this Helm chart on the Red Hat OpenShift platform. # This Helm chart currently supports OpenShift v4.x+. diff --git a/cli/version/version.go b/cli/version/version.go index f68d1632a6..da2c79a1b4 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.5.0" + Version = "1.4.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/api/auth/v2beta1/traffic_permissions_types_test.go b/control-plane/api/auth/v2beta1/traffic_permissions_types_test.go index 85bedb6c40..170f02fb20 100644 --- a/control-plane/api/auth/v2beta1/traffic_permissions_types_test.go +++ b/control-plane/api/auth/v2beta1/traffic_permissions_types_test.go @@ -604,7 +604,7 @@ func TestTrafficPermissions_ObjectMeta(t *testing.T) { // Test defaulting behavior when namespaces are enabled as well as disabled. // TODO: add when implemented -//func TestTrafficPermissions_DefaultNamespaceFields(t *testing.T) +// func TestTrafficPermissions_DefaultNamespaceFields(t *testing.T) func TestTrafficPermissions_Validate(t *testing.T) { cases := []struct { diff --git a/control-plane/api/common/common.go b/control-plane/api/common/common.go index 730fd622ac..53d4c42e96 100644 --- a/control-plane/api/common/common.go +++ b/control-plane/api/common/common.go @@ -29,14 +29,13 @@ const ( RouteAuthFilter string = "routeauthfilter" GatewayPolicy string = "gatewaypolicy" - // V2 resources. + // V2 config entries. TrafficPermissions string = "trafficpermissions" GRPCRoute string = "grpcroute" HTTPRoute string = "httproute" TCPRoute string = "tcproute" ProxyConfiguration string = "proxyconfiguration" MeshGateway string = "meshgateway" - APIGateway string = "apigateway" GatewayClass string = "gatewayclass" GatewayClassConfig string = "gatewayclassconfig" MeshConfiguration string = "meshconfiguration" diff --git a/control-plane/api/mesh/v2beta1/api_gateway_types.go b/control-plane/api/mesh/v2beta1/api_gateway_types.go index fdea0d4422..d9da1d1947 100644 --- a/control-plane/api/mesh/v2beta1/api_gateway_types.go +++ b/control-plane/api/mesh/v2beta1/api_gateway_types.go @@ -12,9 +12,6 @@ import ( "google.golang.org/protobuf/testing/protocmp" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/hashicorp/consul-k8s/control-plane/api/common" inject "github.com/hashicorp/consul-k8s/control-plane/connect-inject/common" @@ -25,7 +22,7 @@ const ( ) func init() { - MeshSchemeBuilder.Register(&GatewayClass{}, &GatewayClassList{}, &APIGateway{}, &APIGatewayList{}) + MeshSchemeBuilder.Register(&GatewayClass{}, &GatewayClassList{}) } // +kubebuilder:object:root=true @@ -40,40 +37,8 @@ type APIGateway struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec pbmesh.APIGateway `json:"spec,omitempty"` - APIGatewayStatus `json:"status,omitempty"` -} - -type APIGatewayStatus struct { - Status `json:"status,omitempty"` - Addresses []GatewayAddress `json:"addresses"` - Listeners []ListenerStatus `json:"listeners"` -} - -func (in *APIGatewayList) ReconcileRequests() []reconcile.Request { - requests := make([]reconcile.Request, 0, len(in.Items)) - - for _, item := range in.Items { - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: item.Name, - Namespace: item.Namespace, - }, - }) - } - return requests -} - -type ListenerStatus struct { - Status `json:"status,omitempty"` - Name string `json:"name"` - AttachedRoutes int32 `json:"attachedRoutes"` -} - -type GatewayAddress struct { - // +kubebuilder:default=IPAddress - Type string `json:"type"` - Value string `json:"value"` + Spec pbmesh.APIGateway `json:"spec,omitempty"` + Status `json:"status,omitempty"` } // +kubebuilder:object:root=true @@ -179,27 +144,3 @@ func (in *APIGateway) Validate(tenancy common.ConsulTenancyConfig) error { // DefaultNamespaceFields is required as part of the common.MeshConfig interface. func (in *APIGateway) DefaultNamespaceFields(tenancy common.ConsulTenancyConfig) {} - -// ListenersToServicePorts converts the APIGateway listeners to ServicePorts. -func (in *APIGateway) ListenersToServicePorts(portModifier int32) []corev1.ServicePort { - ports := []corev1.ServicePort{} - - for _, listener := range in.Spec.Listeners { - port := int32(listener.Port) - ports = append(ports, corev1.ServicePort{ - Name: listener.Name, - Port: port, - TargetPort: intstr.IntOrString{ - IntVal: port + portModifier, - }, - Protocol: corev1.Protocol(listener.Protocol), - }) - } - - return ports -} - -func (in *APIGateway) ListenersToContainerPorts(_ int32, _ int32) []corev1.ContainerPort { - // TODO: check if this is actually needed: we don't map any container ports in v1 - return []corev1.ContainerPort{} -} diff --git a/control-plane/api/mesh/v2beta1/grpc_route_types_test.go b/control-plane/api/mesh/v2beta1/grpc_route_types_test.go index c5ae7864de..07f010bd97 100644 --- a/control-plane/api/mesh/v2beta1/grpc_route_types_test.go +++ b/control-plane/api/mesh/v2beta1/grpc_route_types_test.go @@ -597,7 +597,7 @@ func TestGRPCRoute_ObjectMeta(t *testing.T) { // Test defaulting behavior when namespaces are enabled as well as disabled. // TODO: add when implemented -//func TestGRPCRoute_DefaultNamespaceFields(t *testing.T) +// func TestGRPCRoute_DefaultNamespaceFields(t *testing.T) func TestGRPCRoute_Validate(t *testing.T) { cases := []struct { diff --git a/control-plane/api/mesh/v2beta1/http_route_types_test.go b/control-plane/api/mesh/v2beta1/http_route_types_test.go index 7c9996f185..ecebfb7600 100644 --- a/control-plane/api/mesh/v2beta1/http_route_types_test.go +++ b/control-plane/api/mesh/v2beta1/http_route_types_test.go @@ -803,7 +803,7 @@ func TestHTTPRoute_ObjectMeta(t *testing.T) { // Test defaulting behavior when namespaces are enabled as well as disabled. // TODO: add when implemented -//func TestHTTPRoute_DefaultNamespaceFields(t *testing.T) +// func TestHTTPRoute_DefaultNamespaceFields(t *testing.T) func TestHTTPRoute_Validate(t *testing.T) { cases := []struct { diff --git a/control-plane/api/mesh/v2beta1/mesh_configuration_types.go b/control-plane/api/mesh/v2beta1/mesh_configuration_types.go index 32a19ae2e7..5468168380 100644 --- a/control-plane/api/mesh/v2beta1/mesh_configuration_types.go +++ b/control-plane/api/mesh/v2beta1/mesh_configuration_types.go @@ -7,13 +7,14 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" - "github.com/hashicorp/consul-k8s/control-plane/api/common" - inject "github.com/hashicorp/consul-k8s/control-plane/connect-inject/common" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" "google.golang.org/protobuf/testing/protocmp" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/hashicorp/consul-k8s/control-plane/api/common" + inject "github.com/hashicorp/consul-k8s/control-plane/connect-inject/common" ) const ( diff --git a/control-plane/api/mesh/v2beta1/mesh_gateway_types.go b/control-plane/api/mesh/v2beta1/mesh_gateway_types.go index 4531a2089e..922fd272c2 100644 --- a/control-plane/api/mesh/v2beta1/mesh_gateway_types.go +++ b/control-plane/api/mesh/v2beta1/mesh_gateway_types.go @@ -12,9 +12,6 @@ import ( "google.golang.org/protobuf/testing/protocmp" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - "sigs.k8s.io/controller-runtime/pkg/reconcile" "github.com/hashicorp/consul-k8s/control-plane/api/common" inject "github.com/hashicorp/consul-k8s/control-plane/connect-inject/common" @@ -53,20 +50,6 @@ type MeshGatewayList struct { Items []*MeshGateway `json:"items"` } -func (in *MeshGatewayList) ReconcileRequests() []reconcile.Request { - requests := make([]reconcile.Request, 0, len(in.Items)) - - for _, item := range in.Items { - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Name: item.Name, - Namespace: item.Namespace, - }, - }) - } - return requests -} - func (in *MeshGateway) ResourceID(_, partition string) *pbresource.ID { return &pbresource.ID{ Name: in.Name, @@ -74,6 +57,7 @@ func (in *MeshGateway) ResourceID(_, partition string) *pbresource.ID { Tenancy: &pbresource.Tenancy{ Partition: partition, Namespace: "", // Namespace is always unset because MeshGateway is partition-scoped + }, } } @@ -162,38 +146,3 @@ func (in *MeshGateway) Validate(tenancy common.ConsulTenancyConfig) error { // DefaultNamespaceFields is required as part of the common.MeshConfig interface. func (in *MeshGateway) DefaultNamespaceFields(tenancy common.ConsulTenancyConfig) {} - -// ListenersToServicePorts converts the MeshGateway listeners to ServicePorts. -func (in *MeshGateway) ListenersToServicePorts(portModifier int32) []corev1.ServicePort { - ports := []corev1.ServicePort{} - - for _, listener := range in.Spec.Listeners { - port := int32(listener.Port) - - ports = append(ports, corev1.ServicePort{ - Name: listener.Name, - Port: port, - TargetPort: intstr.IntOrString{ - IntVal: port + portModifier, - }, - Protocol: corev1.Protocol(listener.Protocol), - }) - } - return ports -} - -func (in *MeshGateway) ListenersToContainerPorts(portModifier int32, hostPort int32) []corev1.ContainerPort { - ports := []corev1.ContainerPort{} - - for _, listener := range in.Spec.Listeners { - port := int32(listener.Port) - - ports = append(ports, corev1.ContainerPort{ - Name: listener.Name, - ContainerPort: port + portModifier, - HostPort: hostPort, - Protocol: corev1.Protocol(listener.Protocol), - }) - } - return ports -} diff --git a/control-plane/api/mesh/v2beta1/proxy_configuration_types_test.go b/control-plane/api/mesh/v2beta1/proxy_configuration_types_test.go index 55e6ce45a9..936f3dd9c2 100644 --- a/control-plane/api/mesh/v2beta1/proxy_configuration_types_test.go +++ b/control-plane/api/mesh/v2beta1/proxy_configuration_types_test.go @@ -509,7 +509,7 @@ func TestProxyConfiguration_ObjectMeta(t *testing.T) { // Test defaulting behavior when namespaces are enabled as well as disabled. // TODO: add when implemented -//func TestProxyConfiguration_DefaultNamespaceFields(t *testing.T) +// func TestProxyConfiguration_DefaultNamespaceFields(t *testing.T) func constructProxyConfigurationResource(tp *pbmesh.ProxyConfiguration, name, namespace, partition string) *pbresource.Resource { data := inject.ToProtoAny(tp) diff --git a/control-plane/api/mesh/v2beta1/tcp_route_types_test.go b/control-plane/api/mesh/v2beta1/tcp_route_types_test.go index f03e5232db..fd139058d7 100644 --- a/control-plane/api/mesh/v2beta1/tcp_route_types_test.go +++ b/control-plane/api/mesh/v2beta1/tcp_route_types_test.go @@ -379,7 +379,7 @@ func TestTCPRoute_ObjectMeta(t *testing.T) { // Test defaulting behavior when namespaces are enabled as well as disabled. // TODO: add when implemented -//func TestTCPRoute_DefaultNamespaceFields(t *testing.T) +// func TestTCPRoute_DefaultNamespaceFields(t *testing.T) func TestTCPRoute_Validate(t *testing.T) { cases := []struct { diff --git a/control-plane/api/mesh/v2beta1/zz_generated.deepcopy.go b/control-plane/api/mesh/v2beta1/zz_generated.deepcopy.go index d4ca224b61..9cc59efb3e 100644 --- a/control-plane/api/mesh/v2beta1/zz_generated.deepcopy.go +++ b/control-plane/api/mesh/v2beta1/zz_generated.deepcopy.go @@ -16,7 +16,7 @@ func (in *APIGateway) DeepCopyInto(out *APIGateway) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) in.Spec.DeepCopyInto(&out.Spec) - in.APIGatewayStatus.DeepCopyInto(&out.APIGatewayStatus) + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGateway. @@ -73,34 +73,6 @@ func (in *APIGatewayList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *APIGatewayStatus) DeepCopyInto(out *APIGatewayStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) - if in.Addresses != nil { - in, out := &in.Addresses, &out.Addresses - *out = make([]GatewayAddress, len(*in)) - copy(*out, *in) - } - if in.Listeners != nil { - in, out := &in.Listeners, &out.Listeners - *out = make([]ListenerStatus, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGatewayStatus. -func (in *APIGatewayStatus) DeepCopy() *APIGatewayStatus { - if in == nil { - return nil - } - out := new(APIGatewayStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Condition) DeepCopyInto(out *Condition) { *out = *in @@ -201,21 +173,6 @@ func (in *GRPCRouteList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *GatewayAddress) DeepCopyInto(out *GatewayAddress) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayAddress. -func (in *GatewayAddress) DeepCopy() *GatewayAddress { - if in == nil { - return nil - } - out := new(GatewayAddress) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GatewayClass) DeepCopyInto(out *GatewayClass) { *out = *in @@ -724,22 +681,6 @@ func (in *HTTPRouteList) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ListenerStatus) DeepCopyInto(out *ListenerStatus) { - *out = *in - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListenerStatus. -func (in *ListenerStatus) DeepCopy() *ListenerStatus { - if in == nil { - return nil - } - out := new(ListenerStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MeshConfiguration) DeepCopyInto(out *MeshConfiguration) { *out = *in diff --git a/control-plane/api/multicluster/v2/exported_services_types.go b/control-plane/api/multicluster/v2/exported_services_types.go index 032e10bd03..2e746efbee 100644 --- a/control-plane/api/multicluster/v2/exported_services_types.go +++ b/control-plane/api/multicluster/v2/exported_services_types.go @@ -57,6 +57,7 @@ func (in *ExportedServices) ResourceID(_, partition string) *pbresource.ID { Tenancy: &pbresource.Tenancy{ Partition: partition, Namespace: "", // Namespace is always unset because ExportedServices is partition-scoped + }, } } diff --git a/control-plane/build-support/functions/10-util.sh b/control-plane/build-support/functions/10-util.sh index dfcf5eb361..62bd9acd67 100644 --- a/control-plane/build-support/functions/10-util.sh +++ b/control-plane/build-support/functions/10-util.sh @@ -629,8 +629,7 @@ function update_version_helm { full_consul_version="$5-$3" full_consul_dataplane_version="$7-$3" elif test "$3" == "dev"; then - full_version="${2%.*}-$3" - full_version_k8s_for_chart_version="$2-$3" + 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" @@ -638,7 +637,7 @@ function update_version_helm { 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_k8s_for_chart_version}/g" "${cfile}" + 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}" diff --git a/control-plane/config/crd/bases/auth.consul.hashicorp.com_trafficpermissions.yaml b/control-plane/config/crd/bases/auth.consul.hashicorp.com_trafficpermissions.yaml index ca29923851..3a7699dce4 100644 --- a/control-plane/config/crd/bases/auth.consul.hashicorp.com_trafficpermissions.yaml +++ b/control-plane/config/crd/bases/auth.consul.hashicorp.com_trafficpermissions.yaml @@ -97,25 +97,23 @@ spec: when evaluating rules for the incoming connection. items: properties: - headers: - items: - properties: - exact: - type: string - invert: - type: boolean - name: - type: string - prefix: - type: string - present: - type: boolean - regex: - type: string - suffix: - type: string - type: object - type: array + header: + properties: + exact: + type: string + invert: + type: boolean + name: + type: string + prefix: + type: string + present: + type: boolean + regex: + type: string + suffix: + type: string + type: object methods: description: Methods is the list of HTTP methods. items: @@ -136,25 +134,23 @@ spec: type: array type: object type: array - headers: - items: - properties: - exact: - type: string - invert: - type: boolean - name: - type: string - prefix: - type: string - present: - type: boolean - regex: - type: string - suffix: - type: string - type: object - type: array + header: + properties: + exact: + type: string + invert: + type: boolean + name: + type: string + prefix: + type: string + present: + type: boolean + regex: + type: string + suffix: + type: string + type: object methods: description: Methods is the list of HTTP methods. If no methods are specified, this rule will apply to all methods. diff --git a/control-plane/config/crd/bases/mesh.consul.hashicorp.com_apigateways.yaml b/control-plane/config/crd/bases/mesh.consul.hashicorp.com_apigateways.yaml index e2664016fe..44713c234f 100644 --- a/control-plane/config/crd/bases/mesh.consul.hashicorp.com_apigateways.yaml +++ b/control-plane/config/crd/bases/mesh.consul.hashicorp.com_apigateways.yaml @@ -110,6 +110,13 @@ spec: provide the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer the + resource is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, + provide the wildcard value \"*\" to list resources + across all peers." + type: string type: object type: description: Type identifies the resource's type. @@ -185,113 +192,41 @@ spec: type: object status: properties: - addresses: + conditions: + description: Conditions indicate the latest available observations + of a resource's current state. items: + description: 'Conditions define a readiness condition for a Consul + resource. See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties' properties: - type: - default: IPAddress + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time type: string - value: + message: + description: A human readable message indicating details about + the transition. type: string - required: - - type - - value - type: object - type: array - listeners: - items: - properties: - attachedRoutes: - format: int32 - type: integer - name: + reason: + description: The reason for the condition's last transition. type: string status: - properties: - conditions: - description: Conditions indicate the latest available observations - of a resource's current state. - items: - description: 'Conditions define a readiness condition - for a Consul resource. See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties' - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the - condition transitioned from one status to another. - format: date-time - type: string - message: - description: A human readable message indicating details - about the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, - False, Unknown. - type: string - type: - description: Type of condition. - type: string - required: - - status - - type - type: object - type: array - lastSyncedTime: - description: LastSyncedTime is the last time the resource - successfully synced with Consul. - format: date-time - type: string - type: object + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition. + type: string required: - - attachedRoutes - - name + - status + - type type: object type: array - status: - properties: - conditions: - description: Conditions indicate the latest available observations - of a resource's current state. - items: - description: 'Conditions define a readiness condition for a - Consul resource. See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties' - properties: - lastTransitionTime: - description: LastTransitionTime is the last time the condition - transitioned from one status to another. - format: date-time - type: string - message: - description: A human readable message indicating details - about the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, - Unknown. - type: string - type: - description: Type of condition. - type: string - required: - - status - - type - type: object - type: array - lastSyncedTime: - description: LastSyncedTime is the last time the resource successfully - synced with Consul. - format: date-time - type: string - type: object - required: - - addresses - - listeners + lastSyncedTime: + description: LastSyncedTime is the last time the resource successfully + synced with Consul. + format: date-time + type: string type: object type: object served: true diff --git a/control-plane/config/crd/bases/mesh.consul.hashicorp.com_grpcroutes.yaml b/control-plane/config/crd/bases/mesh.consul.hashicorp.com_grpcroutes.yaml index ff00bd86e5..fda3e4255e 100644 --- a/control-plane/config/crd/bases/mesh.consul.hashicorp.com_grpcroutes.yaml +++ b/control-plane/config/crd/bases/mesh.consul.hashicorp.com_grpcroutes.yaml @@ -68,10 +68,9 @@ spec: description: 'NOTE: roughly equivalent to structs.ResourceReference' properties: port: - description: "For east/west this is the name of the Consul Service + description: For east/west this is the name of the Consul Service port to direct traffic to or empty to imply all. For north/south - this is TBD. \n For more details on potential values of this - field, see documentation for Service.ServicePort." + this is TBD. type: string ref: description: For east/west configuration, this should point @@ -103,6 +102,13 @@ spec: the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer the resource + is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, provide + the wildcard value \"*\" to list resources across + all peers." + type: string type: object type: description: Type identifies the resource's type. @@ -156,9 +162,7 @@ spec: description: "For east/west this is the name of the Consul Service port to direct traffic to or empty to imply using the same value as the parent ref. - For north/south this is TBD. \n For more details - on potential values of this field, see documentation - for Service.ServicePort." + \n For north/south this is TBD." type: string ref: description: For east/west configuration, this should @@ -191,6 +195,13 @@ spec: provide the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer + the resource is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, + provide the wildcard value \"*\" to list + resources across all peers." + type: string type: object type: description: Type identifies the resource's type. diff --git a/control-plane/config/crd/bases/mesh.consul.hashicorp.com_httproutes.yaml b/control-plane/config/crd/bases/mesh.consul.hashicorp.com_httproutes.yaml index ae41db0016..46bf7162a6 100644 --- a/control-plane/config/crd/bases/mesh.consul.hashicorp.com_httproutes.yaml +++ b/control-plane/config/crd/bases/mesh.consul.hashicorp.com_httproutes.yaml @@ -68,10 +68,9 @@ spec: description: 'NOTE: roughly equivalent to structs.ResourceReference' properties: port: - description: "For east/west this is the name of the Consul Service + description: For east/west this is the name of the Consul Service port to direct traffic to or empty to imply all. For north/south - this is TBD. \n For more details on potential values of this - field, see documentation for Service.ServicePort." + this is TBD. type: string ref: description: For east/west configuration, this should point @@ -103,6 +102,13 @@ spec: the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer the resource + is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, provide + the wildcard value \"*\" to list resources across + all peers." + type: string type: object type: description: Type identifies the resource's type. @@ -159,9 +165,7 @@ spec: description: "For east/west this is the name of the Consul Service port to direct traffic to or empty to imply using the same value as the parent ref. - For north/south this is TBD. \n For more details - on potential values of this field, see documentation - for Service.ServicePort." + \n For north/south this is TBD." type: string ref: description: For east/west configuration, this should @@ -194,6 +198,13 @@ spec: provide the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer + the resource is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, + provide the wildcard value \"*\" to list + resources across all peers." + type: string type: object type: description: Type identifies the resource's type. diff --git a/control-plane/config/crd/bases/mesh.consul.hashicorp.com_tcproutes.yaml b/control-plane/config/crd/bases/mesh.consul.hashicorp.com_tcproutes.yaml index dbfb0c9b20..21a3a9c5ec 100644 --- a/control-plane/config/crd/bases/mesh.consul.hashicorp.com_tcproutes.yaml +++ b/control-plane/config/crd/bases/mesh.consul.hashicorp.com_tcproutes.yaml @@ -62,10 +62,9 @@ spec: description: 'NOTE: roughly equivalent to structs.ResourceReference' properties: port: - description: "For east/west this is the name of the Consul Service + description: For east/west this is the name of the Consul Service port to direct traffic to or empty to imply all. For north/south - this is TBD. \n For more details on potential values of this - field, see documentation for Service.ServicePort." + this is TBD. type: string ref: description: For east/west configuration, this should point @@ -97,6 +96,13 @@ spec: the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer the resource + is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, provide + the wildcard value \"*\" to list resources across + all peers." + type: string type: object type: description: Type identifies the resource's type. @@ -141,9 +147,7 @@ spec: description: "For east/west this is the name of the Consul Service port to direct traffic to or empty to imply using the same value as the parent ref. - For north/south this is TBD. \n For more details - on potential values of this field, see documentation - for Service.ServicePort." + \n For north/south this is TBD." type: string ref: description: For east/west configuration, this should @@ -176,6 +180,13 @@ spec: provide the wildcard value \"*\" to list resources across all partitions." type: string + peerName: + description: "PeerName identifies which peer + the resource is imported from. https://developer.hashicorp.com/consul/docs/connect/cluster-peering + \n When using the List and WatchList endpoints, + provide the wildcard value \"*\" to list + resources across all peers." + type: string type: object type: description: Type identifies the resource's type. diff --git a/control-plane/connect-inject/common/annotation_processor.go b/control-plane/connect-inject/common/annotation_processor.go index f89c6348d0..e9ef6d2eff 100644 --- a/control-plane/connect-inject/common/annotation_processor.go +++ b/control-plane/connect-inject/common/annotation_processor.go @@ -107,13 +107,13 @@ func processPodLabeledDestination(pod corev1.Pod, rawUpstream string, enablePart switch end { case "peer": // TODO: uncomment and remove error when peers supported - //peer = strings.TrimSpace(pieces[6]) + // peer = strings.TrimSpace(pieces[6]) return nil, fmt.Errorf("destination currently does not support peers: %s", rawUpstream) case "ap": partition = strings.TrimSpace(pieces[6]) case "dc": // TODO: uncomment and remove error when datacenters are supported - //datacenter = strings.TrimSpace(pieces[6]) + // datacenter = strings.TrimSpace(pieces[6]) return nil, fmt.Errorf("destination currently does not support datacenters: %s", rawUpstream) default: return nil, fmt.Errorf("destination structured incorrectly: %s", rawUpstream) @@ -147,17 +147,17 @@ func processPodLabeledDestination(pod corev1.Pod, rawUpstream string, enablePart switch end { case "peer": // TODO: uncomment and remove error when peers supported - //peer = strings.TrimSpace(pieces[4]) + // peer = strings.TrimSpace(pieces[4]) return nil, fmt.Errorf("destination currently does not support peers: %s", rawUpstream) case "dc": // TODO: uncomment and remove error when datacenter supported - //datacenter = strings.TrimSpace(pieces[4]) + // datacenter = strings.TrimSpace(pieces[4]) return nil, fmt.Errorf("destination currently does not support datacenters: %s", rawUpstream) default: return nil, fmt.Errorf("destination structured incorrectly: %s", rawUpstream) } // TODO: uncomment and remove error when datacenter and/or peers supported - //fallthrough + // fallthrough case 4: if strings.TrimSpace(pieces[3]) == "svc" { svcName = strings.TrimSpace(pieces[2]) @@ -238,7 +238,7 @@ func processPodUnlabeledDestination(pod corev1.Pod, rawUpstream string, enablePa // parse the optional datacenter if len(parts) > 2 { // TODO: uncomment and remove error when datacenters supported - //datacenter = strings.TrimSpace(parts[2]) + // datacenter = strings.TrimSpace(parts[2]) return nil, fmt.Errorf("destination currently does not support datacenters: %s", rawUpstream) } diff --git a/control-plane/connect-inject/common/annotation_processor_test.go b/control-plane/connect-inject/common/annotation_processor_test.go index 77053540e3..3757e26154 100644 --- a/control-plane/connect-inject/common/annotation_processor_test.go +++ b/control-plane/connect-inject/common/annotation_processor_test.go @@ -87,6 +87,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: constants.GetNormalizedConsulNamespace(""), + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream1", // }, @@ -123,6 +124,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: constants.GetNormalizedConsulNamespace(""), + // PeerName: "peer1", // }, // Name: "upstream1", // }, @@ -159,6 +161,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: "ns1", + // PeerName: "peer1", // }, // Name: "upstream1", // }, @@ -229,6 +232,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: "ns1", + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream1", // }, @@ -335,6 +339,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: "ns1", + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream1", // }, @@ -353,6 +358,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: constants.GetNormalizedConsulNamespace(""), + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream2", // }, @@ -371,6 +377,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: "ns1", + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream3", // }, @@ -389,6 +396,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: "ns1", + // PeerName: "peer1", // }, // Name: "upstream4", // }, @@ -805,6 +813,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: constants.GetNormalizedConsulNamespace(""), + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream1", // }, @@ -823,6 +832,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: "bar", + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream2", // }, @@ -841,6 +851,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: "baz", // Namespace: "foo", + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream3", // }, @@ -883,6 +894,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: constants.GetNormalizedConsulNamespace(""), + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream1", // }, @@ -901,6 +913,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: "bar", + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream2", // }, @@ -919,6 +932,7 @@ func TestProcessUpstreams(t *testing.T) { // Tenancy: &pbresource.Tenancy{ // Partition: constants.GetNormalizedConsulPartition(""), // Namespace: "foo", + // PeerName: constants.GetNormalizedConsulPeer(""), // }, // Name: "upstream3", // }, diff --git a/control-plane/connect-inject/controllers/endpointsv2/endpoints_controller.go b/control-plane/connect-inject/controllers/endpointsv2/endpoints_controller.go index 82a9904201..4353590c92 100644 --- a/control-plane/connect-inject/controllers/endpointsv2/endpoints_controller.go +++ b/control-plane/connect-inject/controllers/endpointsv2/endpoints_controller.go @@ -391,7 +391,7 @@ func getServicePorts(service corev1.Service, prefixedPods selectorPodData, exact // // If we otherwise see repeat port values in a K8s service, we pass along and allow Consul to fail validation. if p.Protocol == corev1.ProtocolTCP { - //TODO(NET-5705): Error check reserved "mesh" target port + // TODO(NET-5705): Error check reserved "mesh" target port ports = append(ports, &pbcatalog.ServicePort{ VirtualPort: uint32(p.Port), TargetPort: getEffectiveTargetPort(p.TargetPort, prefixedPods, exactNamePods), @@ -436,7 +436,7 @@ func getEffectiveTargetPort(targetPort intstr.IntOrString, prefixedPods selector // very expensive operation to repeat every time endpoints change, and we don't expect the target port to change // often if ever across pod/deployment lifecycles. // - //TODO(NET-5706) in GA, we intend to change port selection to allow for Consul TargetPort to be numeric. If we + // TODO(NET-5706) in GA, we intend to change port selection to allow for Consul TargetPort to be numeric. If we // retain the port selection model used here beyond GA, we should consider updating it to also consider pod health, // s.t. when the selected port name changes between deployments of a ReplicaSet, we route traffic to ports // belonging to the set most able to serve traffic, rather than simply the largest one. diff --git a/control-plane/connect-inject/controllers/pod/pod_controller.go b/control-plane/connect-inject/controllers/pod/pod_controller.go index 12e2c2124d..febe1d6122 100644 --- a/control-plane/connect-inject/controllers/pod/pod_controller.go +++ b/control-plane/connect-inject/controllers/pod/pod_controller.go @@ -330,7 +330,7 @@ func (r *Controller) writeWorkload(ctx context.Context, pod corev1.Pod) error { // Adding a node does not currently work because the node doesn't exist so its health status will always be // unhealthy, causing any endpoints on that node to also be unhealthy. // TODO: (v2/nitya) Bring this back when node controller is built. - //NodeName: inject.ConsulNodeNameFromK8sNode(pod.Spec.NodeName), + // NodeName: inject.ConsulNodeNameFromK8sNode(pod.Spec.NodeName), Ports: workloadPorts, } data := inject.ToProtoAny(workload) diff --git a/control-plane/connect-inject/controllers/pod/pod_controller_test.go b/control-plane/connect-inject/controllers/pod/pod_controller_test.go index 489010eeb8..605d9dbce9 100644 --- a/control-plane/connect-inject/controllers/pod/pod_controller_test.go +++ b/control-plane/connect-inject/controllers/pod/pod_controller_test.go @@ -819,7 +819,7 @@ func TestDestinationsWrite(t *testing.T) { }, expErr: "error processing destination annotations: destination currently does not support peers: destination.port.upstream1.svc.ns1.ns.peer1.peer:1234", // TODO: uncomment this and remove expErr when peers is supported - //expected: &pbmesh.Destinations{ + // expected: &pbmesh.Destinations{ // Workloads: &pbcatalog.WorkloadSelector{ // Names: []string{podName}, // }, @@ -844,7 +844,7 @@ func TestDestinationsWrite(t *testing.T) { // }, // }, // }, - //}, + // }, consulNamespacesEnabled: true, consulPartitionsEnabled: false, }, @@ -1693,7 +1693,7 @@ func TestReconcileDeletePod(t *testing.T) { var token *api.ACLToken var err error if tc.aclsEnabled { - test.SetupK8sAuthMethodV2(t, testClient.APIClient, tc.podName, metav1.NamespaceDefault) //podName is a standin for the service name + test.SetupK8sAuthMethodV2(t, testClient.APIClient, tc.podName, metav1.NamespaceDefault) // podName is a standin for the service name token, _, err = testClient.APIClient.ACL().Login(&api.ACLLoginParams{ AuthMethod: test.AuthMethod, BearerToken: test.ServiceAccountJWTToken, diff --git a/control-plane/controllers/resources/api-gateway-controller.go b/control-plane/controllers/resources/api-gateway-controller.go deleted file mode 100644 index 2728ef74df..0000000000 --- a/control-plane/controllers/resources/api-gateway-controller.go +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resources - -import ( - "context" - - "github.com/go-logr/logr" - k8serr "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" -) - -// APIGatewayController reconciles a APIGateway object. -type APIGatewayController struct { - client.Client - Log logr.Logger - Scheme *runtime.Scheme - Controller *ConsulResourceController -} - -// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=tcproute,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=mesh.consul.hashicorp.com,resources=tcproute/status,verbs=get;update;patch - -func (r *APIGatewayController) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - logger := r.Logger(req.NamespacedName) - logger.Info("Reconciling APIGateway") - - resource := &meshv2beta1.APIGateway{} - if err := r.Get(ctx, req.NamespacedName, resource); k8serr.IsNotFound(err) { - return ctrl.Result{}, client.IgnoreNotFound(err) - } else if err != nil { - logger.Error(err, "retrieving resource") - return ctrl.Result{}, err - } - - // Call hooks - if !resource.DeletionTimestamp.IsZero() { - logger.Info("deletion event") - - if err := r.onDelete(ctx, req, resource); err != nil { - return ctrl.Result{}, err - } - } else { - if err := r.onCreateUpdate(ctx, req, resource); err != nil { - return ctrl.Result{}, err - } - } - - return r.Controller.ReconcileResource(ctx, r, req, &meshv2beta1.APIGateway{}) -} - -func (r *APIGatewayController) Logger(name types.NamespacedName) logr.Logger { - return r.Log.WithValues("request", name) -} - -func (r *APIGatewayController) UpdateStatus(ctx context.Context, obj client.Object, opts ...client.SubResourceUpdateOption) error { - return r.Status().Update(ctx, obj, opts...) -} - -func (r *APIGatewayController) SetupWithManager(mgr ctrl.Manager) error { - return setupGatewayControllerWithManager[*meshv2beta1.APIGatewayList](mgr, &meshv2beta1.APIGateway{}, r.Client, r, APIGateway_GatewayClassIndex) -} - -func (r *APIGatewayController) onCreateUpdate(ctx context.Context, req ctrl.Request, resource *meshv2beta1.APIGateway) error { - // TODO: NET-7449, NET-7450, and NET-7451 - return nil -} - -func (r *APIGatewayController) onDelete(ctx context.Context, req ctrl.Request, resource *meshv2beta1.APIGateway) error { - // TODO: NET-7449, NET-7450, and NET-7451 - return nil -} diff --git a/control-plane/controllers/resources/api-gateway-controller_test.go b/control-plane/controllers/resources/api-gateway-controller_test.go deleted file mode 100644 index 2bb4eee1c2..0000000000 --- a/control-plane/controllers/resources/api-gateway-controller_test.go +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resources - -import ( - "context" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" - "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" - "github.com/hashicorp/consul-k8s/control-plane/helper/test" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/consul/sdk/testutil" - "github.com/stretchr/testify/require" - "google.golang.org/protobuf/testing/protocmp" - - logrtest "github.com/go-logr/logr/testr" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apimachinery/pkg/types" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client/fake" -) - -func TestAPIGatewayController_ReconcileResourceExists(t *testing.T) { - t.Parallel() - ctx := context.Background() - - s := runtime.NewScheme() - s.AddKnownTypes(schema.GroupVersion{ - Group: "mesh.consul.hashicorp.com", - Version: pbmesh.Version, - }, &v2beta1.APIGateway{}, &v2beta1.APIGatewayList{}) - - apiGW := &v2beta1.APIGateway{ - ObjectMeta: metav1.ObjectMeta{ - Name: "api-gateway", - Namespace: metav1.NamespaceDefault, - }, - Spec: pbmesh.APIGateway{ - GatewayClassName: "consul", - Listeners: []*pbmesh.APIGatewayListener{ - { - Name: "http-listener", - Port: 9090, - Protocol: "http", - }, - }, - }, - } - - fakeClient := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(apiGW).Build() - - testClient := test.TestServerWithMockConnMgrWatcher(t, func(c *testutil.TestServerConfig) { - c.Experiments = []string{"resource-apis"} - }) - - gwCtrl := APIGatewayController{ - Client: fakeClient, - Log: logrtest.New(t), - Scheme: s, - Controller: &ConsulResourceController{ - ConsulClientConfig: testClient.Cfg, - ConsulServerConnMgr: testClient.Watcher, - }, - } - - // ensure the resource is not in consul yet - { - req := &pbresource.ReadRequest{Id: apiGW.ResourceID(constants.DefaultConsulNS, constants.DefaultConsulPartition)} - _, err := testClient.ResourceClient.Read(ctx, req) - require.Error(t, err) - } - - // now reconcile the resource - { - namespacedName := types.NamespacedName{ - Namespace: metav1.NamespaceDefault, - Name: apiGW.KubernetesName(), - } - - // First get it, so we have the latest revision number. - err := fakeClient.Get(ctx, namespacedName, apiGW) - require.NoError(t, err) - - resp, err := gwCtrl.Reconcile(ctx, ctrl.Request{ - NamespacedName: namespacedName, - }) - - require.NoError(t, err) - require.False(t, resp.Requeue) - } - - // now check that the object in Consul is as expected. - { - expectedResource := &pbmesh.APIGateway{ - GatewayClassName: "consul", - Listeners: []*pbmesh.APIGatewayListener{ - { - Name: "http-listener", - Port: 9090, - Protocol: "http", - }, - }, - } - req := &pbresource.ReadRequest{Id: apiGW.ResourceID(constants.DefaultConsulNS, constants.DefaultConsulPartition)} - res, err := testClient.ResourceClient.Read(ctx, req) - require.NoError(t, err) - require.NotNil(t, res) - require.Equal(t, apiGW.GetName(), res.GetResource().GetId().GetName()) - - data := res.GetResource().Data - actual := &pbmesh.APIGateway{} - require.NoError(t, data.UnmarshalTo(actual)) - - opts := append([]cmp.Option{protocmp.IgnoreFields(&pbresource.Resource{}, "status", "generation", "version")}, test.CmpProtoIgnoreOrder()...) - diff := cmp.Diff(expectedResource, actual, opts...) - require.Equal(t, "", diff, "APIGateway does not match") - } -} - -func TestAPIGatewayController_ReconcileAPIGWDoesNotExistInK8s(t *testing.T) { - t.Parallel() - ctx := context.Background() - - s := runtime.NewScheme() - s.AddKnownTypes(schema.GroupVersion{ - Group: "mesh.consul.hashicorp.com", - Version: pbmesh.Version, - }, &v2beta1.APIGateway{}, &v2beta1.APIGatewayList{}) - - fakeClient := fake.NewClientBuilder().WithScheme(s).Build() - - testClient := test.TestServerWithMockConnMgrWatcher(t, func(c *testutil.TestServerConfig) { - c.Experiments = []string{"resource-apis"} - }) - - gwCtrl := APIGatewayController{ - Client: fakeClient, - Log: logrtest.New(t), - Scheme: s, - Controller: &ConsulResourceController{ - ConsulClientConfig: testClient.Cfg, - ConsulServerConnMgr: testClient.Watcher, - }, - } - - // now reconcile the resource - { - namespacedName := types.NamespacedName{ - Namespace: metav1.NamespaceDefault, - Name: "api-gateway", - } - - resp, err := gwCtrl.Reconcile(ctx, ctrl.Request{ - NamespacedName: namespacedName, - }) - - require.NoError(t, err) - require.False(t, resp.Requeue) - require.Equal(t, ctrl.Result{}, resp) - } - - // ensure the resource is not in consul - { - req := &pbresource.ReadRequest{Id: &pbresource.ID{ - Name: "api-gateway", - Type: pbmesh.APIGatewayType, - Tenancy: &pbresource.Tenancy{ - Namespace: constants.DefaultConsulNS, - Partition: constants.DefaultConsulPartition, - }, - }} - - _, err := testClient.ResourceClient.Read(ctx, req) - require.Error(t, err) - } -} diff --git a/control-plane/controllers/resources/gateway_controller_setup.go b/control-plane/controllers/resources/gateway_controller_setup.go deleted file mode 100644 index f58ae1eb13..0000000000 --- a/control-plane/controllers/resources/gateway_controller_setup.go +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resources - -import ( - "context" - - meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - rbacv1 "k8s.io/api/rbac/v1" - "k8s.io/apimachinery/pkg/fields" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/handler" - "sigs.k8s.io/controller-runtime/pkg/reconcile" - "sigs.k8s.io/controller-runtime/pkg/source" -) - -type gatewayList interface { - *meshv2beta1.MeshGatewayList | *meshv2beta1.APIGatewayList - client.ObjectList - ReconcileRequests() []reconcile.Request -} - -func setupGatewayControllerWithManager[L gatewayList](mgr ctrl.Manager, obj client.Object, k8sClient client.Client, gwc reconcile.Reconciler, index indexName) error { - return ctrl.NewControllerManagedBy(mgr). - For(obj). - Owns(&appsv1.Deployment{}). - Owns(&rbacv1.Role{}). - Owns(&rbacv1.RoleBinding{}). - Owns(&corev1.Service{}). - Owns(&corev1.ServiceAccount{}). - Watches( - source.NewKindWithCache(&meshv2beta1.GatewayClass{}, mgr.GetCache()), - handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request { - gc := o.(*meshv2beta1.GatewayClass) - if gc == nil { - return nil - } - - gateways, err := getGatewaysReferencingGatewayClass[L](context.Background(), k8sClient, gc.Name, index) - if err != nil { - return nil - } - - return gateways.ReconcileRequests() - })). - Watches( - source.NewKindWithCache(&meshv2beta1.GatewayClassConfig{}, mgr.GetCache()), - handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request { - gcc := o.(*meshv2beta1.GatewayClassConfig) - if gcc == nil { - return nil - } - - classes, err := getGatewayClassesReferencingGatewayClassConfig(context.Background(), k8sClient, gcc.Name) - if err != nil { - return nil - } - - var requests []reconcile.Request - for _, class := range classes.Items { - if class == nil { - continue - } - - gateways, err := getGatewaysReferencingGatewayClass[L](context.Background(), k8sClient, class.Name, index) - if err != nil { - continue - } - - requests = append(requests, gateways.ReconcileRequests()...) - } - - return requests - })). - Complete(gwc) -} - -// TODO: uncomment when moving the CRUD hooks from mesh gateway controller -//func getGatewayClassConfigByGatewayClassName(ctx context.Context, k8sClient client.Client, className string) (*meshv2beta1.GatewayClassConfig, error) { -// gatewayClass, err := getGatewayClassByName(ctx, k8sClient, className) -// if err != nil { -// return nil, err -// } -// -// if gatewayClass == nil { -// return nil, nil -// } -// -// gatewayClassConfig := &meshv2beta1.GatewayClassConfig{} -// if ref := gatewayClass.Spec.ParametersRef; ref != nil { -// if ref.Group != meshv2beta1.MeshGroup || ref.Kind != v2beta1.KindGatewayClassConfig { -// // TODO @Gateway-Management additionally check for controller name when available -// return nil, nil -// } -// -// if err := k8sClient.Get(ctx, types.NamespacedName{Name: ref.Name}, gatewayClassConfig); err != nil { -// return nil, client.IgnoreNotFound(err) -// } -// } -// return gatewayClassConfig, nil -//} -// -//func getGatewayClassByName(ctx context.Context, k8sClient client.Client, className string) (*meshv2beta1.GatewayClass, error) { -//var gatewayClass meshv2beta1.GatewayClass -// -// if err := k8sClient.Get(ctx, types.NamespacedName{Name: className}, &gatewayClass); err != nil { -// return nil, client.IgnoreNotFound(err) -// } -// return &gatewayClass, nil -//} - -// getGatewayClassesReferencingGatewayClassConfig queries all GatewayClass resources in the -// cluster and returns any that reference the given GatewayClassConfig by name. -func getGatewayClassesReferencingGatewayClassConfig(ctx context.Context, k8sClient client.Client, configName string) (*meshv2beta1.GatewayClassList, error) { - allClasses := &meshv2beta1.GatewayClassList{} - if err := k8sClient.List(ctx, allClasses, &client.ListOptions{ - FieldSelector: fields.OneTermEqualSelector(string(GatewayClass_GatewayClassConfigIndex), configName), - }); err != nil { - return nil, client.IgnoreNotFound(err) - } - - return allClasses, nil -} - -// getGatewaysReferencingGatewayClass queries all xGateway resources in the cluster -// and returns any that reference the given GatewayClass by name. -func getGatewaysReferencingGatewayClass[T gatewayList](ctx context.Context, k8sClient client.Client, className string, index indexName) (T, error) { - var allGateways T - if err := k8sClient.List(ctx, allGateways, &client.ListOptions{ - FieldSelector: fields.OneTermEqualSelector(string(index), className), - }); err != nil { - return nil, client.IgnoreNotFound(err) - } - - return allGateways, nil -} diff --git a/control-plane/controllers/resources/gateway_indices.go b/control-plane/controllers/resources/gateway_indices.go deleted file mode 100644 index 29e221d191..0000000000 --- a/control-plane/controllers/resources/gateway_indices.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package resources - -import ( - "context" - - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - - "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" - meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" -) - -type indexName string - -const ( - // Naming convention: TARGET_REFERENCE. - GatewayClass_GatewayClassConfigIndex indexName = "__v2_gatewayclass_referencing_gatewayclassconfig" - - APIGateway_GatewayClassIndex indexName = "__v2_api_gateway_referencing_gatewayclass" - MeshGateway_GatewayClassIndex indexName = "__v2_mesh_gateway_referencing_gatewayclass" -) - -// RegisterGatewayFieldIndexes registers all of the field indexes for the xGateway controllers. -// These indexes are similar to indexes used in databases to speed up queries. -// They allow us to quickly find objects based on a field value. -func RegisterGatewayFieldIndexes(ctx context.Context, mgr ctrl.Manager) error { - for _, index := range indexes { - if err := mgr.GetFieldIndexer().IndexField(ctx, index.target, string(index.name), index.indexerFunc); err != nil { - return err - } - } - return nil -} - -type index struct { - name indexName - target client.Object - indexerFunc client.IndexerFunc -} - -var indexes = []index{ - { - name: GatewayClass_GatewayClassConfigIndex, - target: &meshv2beta1.GatewayClass{}, - indexerFunc: func(o client.Object) []string { - gc := o.(*meshv2beta1.GatewayClass) - - pr := gc.Spec.ParametersRef - if pr != nil && pr.Kind == v2beta1.KindGatewayClassConfig { - return []string{pr.Name} - } - - return []string{} - }, - }, - { - name: APIGateway_GatewayClassIndex, - target: &meshv2beta1.APIGateway{}, - indexerFunc: func(o client.Object) []string { - g := o.(*meshv2beta1.APIGateway) - return []string{string(g.Spec.GatewayClassName)} - }, - }, - { - name: MeshGateway_GatewayClassIndex, - target: &meshv2beta1.MeshGateway{}, - indexerFunc: func(o client.Object) []string { - g := o.(*meshv2beta1.MeshGateway) - return []string{string(g.Spec.GatewayClassName)} - }, - }, -} diff --git a/control-plane/controllers/resources/mesh_gateway_controller.go b/control-plane/controllers/resources/mesh_gateway_controller.go index 4fb9b0518c..8cc2b61a7c 100644 --- a/control-plane/controllers/resources/mesh_gateway_controller.go +++ b/control-plane/controllers/resources/mesh_gateway_controller.go @@ -19,6 +19,9 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" "github.com/hashicorp/consul-k8s/control-plane/gateways" @@ -77,7 +80,57 @@ func (r *MeshGatewayController) UpdateStatus(ctx context.Context, obj client.Obj } func (r *MeshGatewayController) SetupWithManager(mgr ctrl.Manager) error { - return setupGatewayControllerWithManager[*meshv2beta1.MeshGatewayList](mgr, &meshv2beta1.MeshGateway{}, r.Client, r, MeshGateway_GatewayClassIndex) + return ctrl.NewControllerManagedBy(mgr). + For(&meshv2beta1.MeshGateway{}). + Owns(&appsv1.Deployment{}). + Owns(&rbacv1.Role{}). + Owns(&rbacv1.RoleBinding{}). + Owns(&corev1.Service{}). + Owns(&corev1.ServiceAccount{}). + Watches( + source.NewKindWithCache(&meshv2beta1.GatewayClass{}, mgr.GetCache()), + handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request { + gateways, err := r.getGatewaysReferencingGatewayClass(context.Background(), o.(*meshv2beta1.GatewayClass)) + if err != nil { + return nil + } + + requests := make([]reconcile.Request, 0, len(gateways.Items)) + for _, gateway := range gateways.Items { + requests = append(requests, reconcile.Request{NamespacedName: types.NamespacedName{ + Namespace: gateway.Namespace, + Name: gateway.Name, + }}) + } + + return requests + })). + Watches( + source.NewKindWithCache(&meshv2beta1.GatewayClassConfig{}, mgr.GetCache()), + handler.EnqueueRequestsFromMapFunc(func(o client.Object) []reconcile.Request { + classes, err := r.getGatewayClassesReferencingGatewayClassConfig(context.Background(), o.(*meshv2beta1.GatewayClassConfig)) + if err != nil { + return nil + } + + var requests []reconcile.Request + for _, class := range classes.Items { + gateways, err := r.getGatewaysReferencingGatewayClass(context.Background(), class) + if err != nil { + continue + } + + for _, gateway := range gateways.Items { + requests = append(requests, reconcile.Request{NamespacedName: types.NamespacedName{ + Namespace: gateway.Namespace, + Name: gateway.Name, + }}) + } + } + + return requests + })). + Complete(r) } // onCreateUpdate is responsible for creating/updating all K8s resources that @@ -96,7 +149,7 @@ func (r *MeshGatewayController) onCreateUpdate(ctx context.Context, req ctrl.Req return err } - builder := gateways.NewGatewayBuilder[*meshv2beta1.MeshGateway](resource, r.GatewayConfig, gcc) + builder := gateways.NewMeshGatewayBuilder(resource, r.GatewayConfig, gcc) // Create ServiceAccount desiredAccount := builder.ServiceAccount() @@ -280,3 +333,45 @@ func (r *MeshGatewayController) getGatewayClassForGateway(ctx context.Context, g } return &gatewayClass, nil } + +// getGatewayClassesReferencingGatewayClassConfig queries all GatewayClass resources in the +// cluster and returns any that reference the given GatewayClassConfig. +func (r *MeshGatewayController) getGatewayClassesReferencingGatewayClassConfig(ctx context.Context, config *meshv2beta1.GatewayClassConfig) (*meshv2beta1.GatewayClassList, error) { + if config == nil { + return nil, nil + } + + allClasses := &meshv2beta1.GatewayClassList{} + if err := r.Client.List(ctx, allClasses); err != nil { + return nil, client.IgnoreNotFound(err) + } + + matchingClasses := &meshv2beta1.GatewayClassList{} + for _, class := range allClasses.Items { + if class.Spec.ParametersRef != nil && class.Spec.ParametersRef.Name == config.Name { + matchingClasses.Items = append(matchingClasses.Items, class) + } + } + return matchingClasses, nil +} + +// getGatewaysReferencingGatewayClass queries all MeshGateway resources in the cluster +// and returns any that reference the given GatewayClass. +func (r *MeshGatewayController) getGatewaysReferencingGatewayClass(ctx context.Context, class *meshv2beta1.GatewayClass) (*meshv2beta1.MeshGatewayList, error) { + if class == nil { + return nil, nil + } + + allGateways := &meshv2beta1.MeshGatewayList{} + if err := r.Client.List(ctx, allGateways); err != nil { + return nil, client.IgnoreNotFound(err) + } + + matchingGateways := &meshv2beta1.MeshGatewayList{} + for _, gateway := range allGateways.Items { + if gateway.Spec.GatewayClassName == class.Name { + matchingGateways.Items = append(matchingGateways.Items, gateway) + } + } + return matchingGateways, nil +} diff --git a/control-plane/gateways/builder.go b/control-plane/gateways/builder.go index 36209a8d19..e43e6dd890 100644 --- a/control-plane/gateways/builder.go +++ b/control-plane/gateways/builder.go @@ -5,30 +5,21 @@ package gateways import ( meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" - corev1 "k8s.io/api/core/v1" - "sigs.k8s.io/controller-runtime/pkg/client" ) -type Gateway interface { - *meshv2beta1.MeshGateway | *meshv2beta1.APIGateway - client.Object - ListenersToServicePorts(int32) []corev1.ServicePort - ListenersToContainerPorts(int32, int32) []corev1.ContainerPort -} - -// gatewayBuilder is a helper struct for building the Kubernetes resources for a mesh gateway. +// meshGatewayBuilder is a helper struct for building the Kubernetes resources for a mesh gateway. // This includes Deployment, Role, Service, and ServiceAccount resources. // Configuration is combined from the MeshGateway, GatewayConfig, and GatewayClassConfig. -type gatewayBuilder[T Gateway] struct { - gateway T - gcc *meshv2beta1.GatewayClassConfig +type meshGatewayBuilder struct { + gateway *meshv2beta1.MeshGateway config GatewayConfig + gcc *meshv2beta1.GatewayClassConfig } -// NewGatewayBuilder returns a new meshGatewayBuilder for the given MeshGateway, +// NewMeshGatewayBuilder returns a new meshGatewayBuilder for the given MeshGateway, // GatewayConfig, and GatewayClassConfig. -func NewGatewayBuilder[T Gateway](gateway T, gatewayConfig GatewayConfig, gatewayClassConfig *meshv2beta1.GatewayClassConfig) *gatewayBuilder[T] { - return &gatewayBuilder[T]{ +func NewMeshGatewayBuilder(gateway *meshv2beta1.MeshGateway, gatewayConfig GatewayConfig, gatewayClassConfig *meshv2beta1.GatewayClassConfig) *meshGatewayBuilder { + return &meshGatewayBuilder{ gateway: gateway, config: gatewayConfig, gcc: gatewayClassConfig, diff --git a/control-plane/gateways/deployment.go b/control-plane/gateways/deployment.go index 9e7fef2838..433323489c 100644 --- a/control-plane/gateways/deployment.go +++ b/control-plane/gateways/deployment.go @@ -18,12 +18,12 @@ const ( meshGatewayAnnotationKind = "mesh-gateway" ) -func (b *gatewayBuilder[T]) Deployment() (*appsv1.Deployment, error) { +func (b *meshGatewayBuilder) Deployment() (*appsv1.Deployment, error) { spec, err := b.deploymentSpec() return &appsv1.Deployment{ ObjectMeta: metav1.ObjectMeta{ - Name: b.gateway.GetName(), - Namespace: b.gateway.GetNamespace(), + Name: b.gateway.Name, + Namespace: b.gateway.Namespace, Labels: b.labelsForDeployment(), Annotations: b.annotationsForDeployment(), }, @@ -31,7 +31,7 @@ func (b *gatewayBuilder[T]) Deployment() (*appsv1.Deployment, error) { }, err } -func (b *gatewayBuilder[T]) deploymentSpec() (*appsv1.DeploymentSpec, error) { +func (b *meshGatewayBuilder) deploymentSpec() (*appsv1.DeploymentSpec, error) { var ( deploymentConfig meshv2beta1.GatewayClassDeploymentConfig containerConfig meshv2beta1.GatewayClassContainerConfig @@ -74,11 +74,11 @@ func (b *gatewayBuilder[T]) deploymentSpec() (*appsv1.DeploymentSpec, error) { constants.AnnotationTransparentProxyOverwriteProbes: "false", // This annotation determines which source to use to set the // WAN address and WAN port for the Mesh Gateway service registration. - constants.AnnotationGatewayWANSource: b.gateway.GetAnnotations()[constants.AnnotationGatewayWANSource], + constants.AnnotationGatewayWANSource: b.gateway.Annotations[constants.AnnotationGatewayWANSource], // This annotation determines the WAN port for the Mesh Gateway service registration. - constants.AnnotationGatewayWANPort: b.gateway.GetAnnotations()[constants.AnnotationGatewayWANPort], + constants.AnnotationGatewayWANPort: b.gateway.Annotations[constants.AnnotationGatewayWANPort], // This annotation determines the address for the gateway when the source annotation is "Static". - constants.AnnotationGatewayWANAddress: b.gateway.GetAnnotations()[constants.AnnotationGatewayWANAddress], + constants.AnnotationGatewayWANAddress: b.gateway.Annotations[constants.AnnotationGatewayWANAddress], }, }, Spec: corev1.PodSpec{ diff --git a/control-plane/gateways/deployment_dataplane_container.go b/control-plane/gateways/deployment_dataplane_container.go index 630e337ad5..9dc7dad141 100644 --- a/control-plane/gateways/deployment_dataplane_container.go +++ b/control-plane/gateways/deployment_dataplane_container.go @@ -27,7 +27,7 @@ const ( volumeName = "consul-mesh-inject-data" ) -func (b *gatewayBuilder[T]) consulDataplaneContainer(containerConfig v2beta1.GatewayClassContainerConfig) (corev1.Container, error) { +func (b *meshGatewayBuilder) consulDataplaneContainer(containerConfig v2beta1.GatewayClassContainerConfig) (corev1.Container, error) { // Extract the service account token's volume mount. var ( err error @@ -56,7 +56,7 @@ func (b *gatewayBuilder[T]) consulDataplaneContainer(containerConfig v2beta1.Gat } container := corev1.Container{ - Name: b.gateway.GetName(), + Name: b.gateway.Name, Image: b.config.ImageDataplane, // We need to set tmp dir to an ephemeral volume that we're mounting so that @@ -117,7 +117,16 @@ func (b *gatewayBuilder[T]) consulDataplaneContainer(containerConfig v2beta1.Gat ContainerPort: int32(constants.ProxyDefaultHealthPort), }) - container.Ports = append(container.Ports, b.gateway.ListenersToContainerPorts(containerConfig.PortModifier, containerConfig.HostPort)...) + // Configure the wan port. + wanPort := corev1.ContainerPort{ + Name: "wan", + ContainerPort: int32(constants.DefaultWANPort), + HostPort: containerConfig.HostPort, + } + + wanPort.ContainerPort = 443 + containerConfig.PortModifier + + container.Ports = append(container.Ports, wanPort) // Configure the resource requests and limits for the proxy if they are set. if resources != nil { @@ -140,7 +149,7 @@ func (b *gatewayBuilder[T]) consulDataplaneContainer(containerConfig v2beta1.Gat return container, nil } -func (b *gatewayBuilder[T]) dataplaneArgs(bearerTokenFile string) ([]string, error) { +func (b *meshGatewayBuilder) dataplaneArgs(bearerTokenFile string) ([]string, error) { args := []string{ "-addresses", b.config.ConsulConfig.Address, "-grpc-port=" + strconv.Itoa(b.config.ConsulConfig.GRPCPort), @@ -149,14 +158,14 @@ func (b *gatewayBuilder[T]) dataplaneArgs(bearerTokenFile string) ([]string, err "-envoy-concurrency=" + defaultEnvoyProxyConcurrency, } - consulNamespace := namespaces.ConsulNamespace(b.gateway.GetNamespace(), b.config.ConsulTenancyConfig.EnableConsulNamespaces, b.config.ConsulTenancyConfig.ConsulDestinationNamespace, b.config.ConsulTenancyConfig.EnableConsulNamespaces, b.config.ConsulTenancyConfig.NSMirroringPrefix) + consulNamespace := namespaces.ConsulNamespace(b.gateway.Namespace, b.config.ConsulTenancyConfig.EnableConsulNamespaces, b.config.ConsulTenancyConfig.ConsulDestinationNamespace, b.config.ConsulTenancyConfig.EnableConsulNamespaces, b.config.ConsulTenancyConfig.NSMirroringPrefix) if b.config.AuthMethod != "" { args = append(args, "-credential-type=login", "-login-auth-method="+b.config.AuthMethod, "-login-bearer-token-path="+bearerTokenFile, - "-login-meta="+fmt.Sprintf("gateway=%s/%s", b.gateway.GetNamespace(), b.gateway.GetName()), + "-login-meta="+fmt.Sprintf("gateway=%s/%s", b.gateway.Namespace, b.gateway.Name), ) if b.config.ConsulTenancyConfig.ConsulPartition != "" { args = append(args, "-login-partition="+b.config.ConsulTenancyConfig.ConsulPartition) diff --git a/control-plane/gateways/deployment_init_container.go b/control-plane/gateways/deployment_init_container.go index beb7267005..14230b98df 100644 --- a/control-plane/gateways/deployment_init_container.go +++ b/control-plane/gateways/deployment_init_container.go @@ -21,7 +21,9 @@ const ( initContainersUserAndGroupID = 5996 ) -var tpl = template.Must(template.New("root").Parse(strings.TrimSpace(initContainerCommandTpl))) +var ( + tpl = template.Must(template.New("root").Parse(strings.TrimSpace(initContainerCommandTpl))) +) type initContainerCommandData struct { ServiceName string @@ -35,12 +37,12 @@ type initContainerCommandData struct { // initContainer returns the init container spec for connect-init that polls for the service and the connect proxy service to be registered // so that it can save the proxy service id to the shared volume and boostrap Envoy with the proxy-id. -func (b *gatewayBuilder[T]) initContainer() (corev1.Container, error) { +func (b *meshGatewayBuilder) initContainer() (corev1.Container, error) { data := initContainerCommandData{ AuthMethod: b.config.AuthMethod, LogLevel: b.logLevelForInitContainer(), LogJSON: b.config.LogJSON, - ServiceName: b.gateway.GetName(), + ServiceName: b.gateway.Name, ServiceAccountName: b.serviceAccountName(), } // Render the command @@ -62,7 +64,7 @@ func (b *gatewayBuilder[T]) initContainer() (corev1.Container, error) { bearerTokenFile = defaultBearerTokenFile } - consulNamespace := namespaces.ConsulNamespace(b.gateway.GetNamespace(), b.config.ConsulTenancyConfig.EnableConsulNamespaces, b.config.ConsulTenancyConfig.ConsulDestinationNamespace, b.config.ConsulTenancyConfig.EnableConsulNamespaces, b.config.ConsulTenancyConfig.NSMirroringPrefix) + consulNamespace := namespaces.ConsulNamespace(b.gateway.Namespace, b.config.ConsulTenancyConfig.EnableConsulNamespaces, b.config.ConsulTenancyConfig.ConsulDestinationNamespace, b.config.ConsulTenancyConfig.EnableConsulNamespaces, b.config.ConsulTenancyConfig.NSMirroringPrefix) initContainerName := injectInitContainerName container := corev1.Container{ diff --git a/control-plane/gateways/deployment_test.go b/control-plane/gateways/deployment_test.go index 2444d02e3d..12fa30ee0c 100644 --- a/control-plane/gateways/deployment_test.go +++ b/control-plane/gateways/deployment_test.go @@ -42,7 +42,7 @@ RQIgXg8YtejEgGNxswtyXsvqzhLpt7k44L7TJMUhfIw0lUECIQCIxKNowmv0/XVz nRnYLmGy79EZ2Y+CZS9nSm9Es6QNwg== │ -----END CERTIFICATE-----` -func Test_gatewayBuilder_Deployment(t *testing.T) { +func Test_meshGatewayBuilder_Deployment(t *testing.T) { type fields struct { gateway *meshv2beta1.MeshGateway config GatewayConfig @@ -67,13 +67,6 @@ func Test_gatewayBuilder_Deployment(t *testing.T) { }, Spec: pbmesh.MeshGateway{ GatewayClassName: "test-gateway-class", - Listeners: []*pbmesh.MeshGatewayListener{ - { - Name: "wan", - Port: 443, - Protocol: "tcp", - }, - }, }, }, config: GatewayConfig{}, @@ -334,7 +327,6 @@ func Test_gatewayBuilder_Deployment(t *testing.T) { Name: "wan", ContainerPort: 8443, HostPort: 8080, - Protocol: "tcp", }, }, Env: []corev1.EnvVar{ @@ -483,13 +475,6 @@ func Test_gatewayBuilder_Deployment(t *testing.T) { }, Spec: pbmesh.MeshGateway{ GatewayClassName: "test-gateway-class", - Listeners: []*pbmesh.MeshGatewayListener{ - { - Name: "wan", - Port: 443, - Protocol: "tcp", - }, - }, }, }, config: GatewayConfig{ @@ -743,7 +728,6 @@ func Test_gatewayBuilder_Deployment(t *testing.T) { Name: "wan", ContainerPort: 8443, HostPort: 8080, - Protocol: "tcp", }, }, Env: []corev1.EnvVar{ @@ -892,13 +876,6 @@ func Test_gatewayBuilder_Deployment(t *testing.T) { }, Spec: pbmesh.MeshGateway{ GatewayClassName: "test-gateway-class", - Listeners: []*pbmesh.MeshGatewayListener{ - { - Name: "wan", - Port: 443, - Protocol: "tcp", - }, - }, }, }, config: GatewayConfig{}, @@ -1032,7 +1009,6 @@ func Test_gatewayBuilder_Deployment(t *testing.T) { { Name: "wan", ContainerPort: 443, - Protocol: "tcp", }, }, Env: []corev1.EnvVar{ @@ -1139,7 +1115,7 @@ func Test_gatewayBuilder_Deployment(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - b := &gatewayBuilder[*meshv2beta1.MeshGateway]{ + b := &meshGatewayBuilder{ gateway: tt.fields.gateway, config: tt.fields.config, gcc: tt.fields.gcc, diff --git a/control-plane/gateways/metadata.go b/control-plane/gateways/metadata.go index 4581efc232..e1479ef3f2 100644 --- a/control-plane/gateways/metadata.go +++ b/control-plane/gateways/metadata.go @@ -13,54 +13,54 @@ const labelManagedBy = "mesh.consul.hashicorp.com/managed-by" var defaultLabels = map[string]string{labelManagedBy: "consul-k8s"} -func (b *gatewayBuilder[T]) annotationsForDeployment() map[string]string { +func (b *meshGatewayBuilder) annotationsForDeployment() map[string]string { if b.gcc == nil { return map[string]string{} } - return computeAnnotationsOrLabels(b.gateway.GetAnnotations(), b.gcc.Spec.Deployment.Annotations, b.gcc.Spec.Annotations) + return computeAnnotationsOrLabels(b.gateway.Annotations, b.gcc.Spec.Deployment.Annotations, b.gcc.Spec.Annotations) } -func (b *gatewayBuilder[T]) annotationsForRole() map[string]string { +func (b *meshGatewayBuilder) annotationsForRole() map[string]string { if b.gcc == nil { return map[string]string{} } - return computeAnnotationsOrLabels(b.gateway.GetAnnotations(), b.gcc.Spec.Role.Annotations, b.gcc.Spec.Annotations) + return computeAnnotationsOrLabels(b.gateway.Annotations, b.gcc.Spec.Role.Annotations, b.gcc.Spec.Annotations) } -func (b *gatewayBuilder[T]) annotationsForRoleBinding() map[string]string { +func (b *meshGatewayBuilder) annotationsForRoleBinding() map[string]string { if b.gcc == nil { return map[string]string{} } - return computeAnnotationsOrLabels(b.gateway.GetAnnotations(), b.gcc.Spec.RoleBinding.Annotations, b.gcc.Spec.Annotations) + return computeAnnotationsOrLabels(b.gateway.Annotations, b.gcc.Spec.RoleBinding.Annotations, b.gcc.Spec.Annotations) } -func (b *gatewayBuilder[T]) annotationsForService() map[string]string { +func (b *meshGatewayBuilder) annotationsForService() map[string]string { if b.gcc == nil { return map[string]string{} } - return computeAnnotationsOrLabels(b.gateway.GetAnnotations(), b.gcc.Spec.Service.Annotations, b.gcc.Spec.Annotations) + return computeAnnotationsOrLabels(b.gateway.Annotations, b.gcc.Spec.Service.Annotations, b.gcc.Spec.Annotations) } -func (b *gatewayBuilder[T]) annotationsForServiceAccount() map[string]string { +func (b *meshGatewayBuilder) annotationsForServiceAccount() map[string]string { if b.gcc == nil { return map[string]string{} } - return computeAnnotationsOrLabels(b.gateway.GetAnnotations(), b.gcc.Spec.ServiceAccount.Annotations, b.gcc.Spec.Annotations) + return computeAnnotationsOrLabels(b.gateway.Annotations, b.gcc.Spec.ServiceAccount.Annotations, b.gcc.Spec.Annotations) } -func (b *gatewayBuilder[T]) labelsForDeployment() map[string]string { +func (b *meshGatewayBuilder) labelsForDeployment() map[string]string { if b.gcc == nil { return defaultLabels } - labels := computeAnnotationsOrLabels(b.gateway.GetLabels(), b.gcc.Spec.Deployment.Labels, b.gcc.Spec.Labels) + labels := computeAnnotationsOrLabels(b.gateway.Labels, b.gcc.Spec.Deployment.Labels, b.gcc.Spec.Labels) for k, v := range defaultLabels { labels[k] = v } return labels } -func (b *gatewayBuilder[T]) logLevelForDataplaneContainer() string { +func (b *meshGatewayBuilder) logLevelForDataplaneContainer() string { if b.config.LogLevel != "" { return b.config.LogLevel } @@ -72,7 +72,7 @@ func (b *gatewayBuilder[T]) logLevelForDataplaneContainer() string { return b.gcc.Spec.Deployment.Container.Consul.Logging.Level } -func (b *gatewayBuilder[T]) logLevelForInitContainer() string { +func (b *meshGatewayBuilder) logLevelForInitContainer() string { if b.config.LogLevel != "" { return b.config.LogLevel } @@ -84,48 +84,48 @@ func (b *gatewayBuilder[T]) logLevelForInitContainer() string { return b.gcc.Spec.Deployment.InitContainer.Consul.Logging.Level } -func (b *gatewayBuilder[T]) labelsForRole() map[string]string { +func (b *meshGatewayBuilder) labelsForRole() map[string]string { if b.gcc == nil { return defaultLabels } - labels := computeAnnotationsOrLabels(b.gateway.GetLabels(), b.gcc.Spec.Role.Labels, b.gcc.Spec.Labels) + labels := computeAnnotationsOrLabels(b.gateway.Labels, b.gcc.Spec.Role.Labels, b.gcc.Spec.Labels) for k, v := range defaultLabels { labels[k] = v } return labels } -func (b *gatewayBuilder[T]) labelsForRoleBinding() map[string]string { +func (b *meshGatewayBuilder) labelsForRoleBinding() map[string]string { if b.gcc == nil { return defaultLabels } - labels := computeAnnotationsOrLabels(b.gateway.GetLabels(), b.gcc.Spec.RoleBinding.Labels, b.gcc.Spec.Labels) + labels := computeAnnotationsOrLabels(b.gateway.Labels, b.gcc.Spec.RoleBinding.Labels, b.gcc.Spec.Labels) for k, v := range defaultLabels { labels[k] = v } return labels } -func (b *gatewayBuilder[T]) labelsForService() map[string]string { +func (b *meshGatewayBuilder) labelsForService() map[string]string { if b.gcc == nil { return defaultLabels } - labels := computeAnnotationsOrLabels(b.gateway.GetLabels(), b.gcc.Spec.Service.Labels, b.gcc.Spec.Labels) + labels := computeAnnotationsOrLabels(b.gateway.Labels, b.gcc.Spec.Service.Labels, b.gcc.Spec.Labels) for k, v := range defaultLabels { labels[k] = v } return labels } -func (b *gatewayBuilder[T]) labelsForServiceAccount() map[string]string { +func (b *meshGatewayBuilder) labelsForServiceAccount() map[string]string { if b.gcc == nil { return defaultLabels } - labels := computeAnnotationsOrLabels(b.gateway.GetLabels(), b.gcc.Spec.ServiceAccount.Labels, b.gcc.Spec.Labels) + labels := computeAnnotationsOrLabels(b.gateway.Labels, b.gcc.Spec.ServiceAccount.Labels, b.gcc.Spec.Labels) for k, v := range defaultLabels { labels[k] = v } diff --git a/control-plane/gateways/metadata_test.go b/control-plane/gateways/metadata_test.go index 88958c1d5c..7505867992 100644 --- a/control-plane/gateways/metadata_test.go +++ b/control-plane/gateways/metadata_test.go @@ -12,7 +12,7 @@ import ( meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" ) -func TestGatewayBuilder_Annotations(t *testing.T) { +func TestMeshGatewayBuilder_Annotations(t *testing.T) { gateway := &meshv2beta1.MeshGateway{ ObjectMeta: metav1.ObjectMeta{ Annotations: map[string]string{ @@ -77,7 +77,7 @@ func TestGatewayBuilder_Annotations(t *testing.T) { }, } - b := NewGatewayBuilder[*meshv2beta1.MeshGateway](gateway, GatewayConfig{}, gatewayClassConfig) + b := NewMeshGatewayBuilder(gateway, GatewayConfig{}, gatewayClassConfig) for _, testCase := range []struct { Actual map[string]string @@ -133,7 +133,7 @@ func TestGatewayBuilder_Annotations(t *testing.T) { } } -func TestGatewayBuilder_Labels(t *testing.T) { +func TestNewMeshGatewayBuilder_Labels(t *testing.T) { gateway := &meshv2beta1.MeshGateway{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ @@ -198,7 +198,7 @@ func TestGatewayBuilder_Labels(t *testing.T) { }, } - b := NewGatewayBuilder[*meshv2beta1.MeshGateway](gateway, GatewayConfig{}, gatewayClassConfig) + b := NewMeshGatewayBuilder(gateway, GatewayConfig{}, gatewayClassConfig) for _, testCase := range []struct { Actual map[string]string @@ -261,7 +261,7 @@ func TestGatewayBuilder_Labels(t *testing.T) { // The LogLevel for deployment containers may be set on the Gateway Class Config or the Gateway Config. // If it is set on both, the Gateway Config takes precedence. -func TestGatewayBuilder_LogLevel(t *testing.T) { +func TestMeshGatewayBuilder_LogLevel(t *testing.T) { debug := "debug" info := "info" @@ -285,6 +285,7 @@ func TestGatewayBuilder_LogLevel(t *testing.T) { for name, testCase := range testCases { t.Run(name, func(t *testing.T) { + gcc := &meshv2beta1.GatewayClassConfig{ Spec: meshv2beta1.GatewayClassConfigSpec{ Deployment: meshv2beta1.GatewayClassDeploymentConfig{ @@ -298,7 +299,7 @@ func TestGatewayBuilder_LogLevel(t *testing.T) { }, }, } - b := NewGatewayBuilder(&meshv2beta1.MeshGateway{}, GatewayConfig{LogLevel: testCase.GatewayLogLevel}, gcc) + b := NewMeshGatewayBuilder(&meshv2beta1.MeshGateway{}, GatewayConfig{LogLevel: testCase.GatewayLogLevel}, gcc) assert.Equal(t, debug, b.logLevelForDataplaneContainer()) }) diff --git a/control-plane/gateways/role.go b/control-plane/gateways/role.go index 0cec287b5b..3264bb60b0 100644 --- a/control-plane/gateways/role.go +++ b/control-plane/gateways/role.go @@ -8,11 +8,11 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func (b *gatewayBuilder[T]) Role() *rbacv1.Role { +func (b *meshGatewayBuilder) Role() *rbacv1.Role { return &rbacv1.Role{ ObjectMeta: metav1.ObjectMeta{ - Name: b.gateway.GetName(), - Namespace: b.gateway.GetNamespace(), + Name: b.gateway.Name, + Namespace: b.gateway.Namespace, Labels: b.labelsForRole(), Annotations: b.annotationsForRole(), }, @@ -20,11 +20,11 @@ func (b *gatewayBuilder[T]) Role() *rbacv1.Role { } } -func (b *gatewayBuilder[T]) RoleBinding() *rbacv1.RoleBinding { +func (b *meshGatewayBuilder) RoleBinding() *rbacv1.RoleBinding { return &rbacv1.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ - Name: b.gateway.GetName(), - Namespace: b.gateway.GetNamespace(), + Name: b.gateway.Name, + Namespace: b.gateway.Namespace, Labels: b.labelsForRoleBinding(), Annotations: b.annotationsForRoleBinding(), }, @@ -32,8 +32,8 @@ func (b *gatewayBuilder[T]) RoleBinding() *rbacv1.RoleBinding { { APIGroup: "", Kind: rbacv1.ServiceAccountKind, - Name: b.gateway.GetName(), - Namespace: b.gateway.GetNamespace(), + Name: b.gateway.Name, + Namespace: b.gateway.Namespace, }, }, RoleRef: rbacv1.RoleRef{ diff --git a/control-plane/gateways/service.go b/control-plane/gateways/service.go index b60cc42019..c7dffdf969 100644 --- a/control-plane/gateways/service.go +++ b/control-plane/gateways/service.go @@ -6,11 +6,13 @@ package gateways import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" + "github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants" ) -func (b *gatewayBuilder[T]) Service() *corev1.Service { +func (b *meshGatewayBuilder) Service() *corev1.Service { var ( containerConfig *meshv2beta1.GatewayClassContainerConfig portModifier = int32(0) @@ -25,19 +27,53 @@ func (b *gatewayBuilder[T]) Service() *corev1.Service { return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ - Name: b.gateway.GetName(), - Namespace: b.gateway.GetNamespace(), + Name: b.gateway.Name, + Namespace: b.gateway.Namespace, Labels: b.labelsForService(), Annotations: b.annotationsForService(), }, Spec: corev1.ServiceSpec{ Selector: b.labelsForDeployment(), Type: serviceType, - Ports: b.gateway.ListenersToServicePorts(portModifier), + Ports: b.Ports(portModifier), }, } } +// Ports build a list of ports from the listener objects. In theory there should only ever be a WAN port on +// mesh gateway but building the ports from a list of listeners will allow for easier compatability with other +// gateway patterns in the future. +func (b *meshGatewayBuilder) Ports(portModifier int32) []corev1.ServicePort { + + ports := []corev1.ServicePort{} + + if len(b.gateway.Spec.Listeners) == 0 { + //If empty use the default value. This should always be set, but in case it's not, this check + //will prevent a panic. + return []corev1.ServicePort{ + { + Name: "wan", + Port: constants.DefaultWANPort, + TargetPort: intstr.IntOrString{ + IntVal: constants.DefaultWANPort + portModifier, + }, + }, + } + } + for _, listener := range b.gateway.Spec.Listeners { + port := int32(listener.Port) + ports = append(ports, corev1.ServicePort{ + Name: listener.Name, + Port: port, + TargetPort: intstr.IntOrString{ + IntVal: port + portModifier, + }, + Protocol: corev1.Protocol(listener.Protocol), + }) + } + return ports +} + // MergeService is used to update a corev1.Service without overwriting any // existing annotations or labels that were placed there by other vendors. // diff --git a/control-plane/gateways/service_test.go b/control-plane/gateways/service_test.go index 19e9a0e71d..f5d4beb58c 100644 --- a/control-plane/gateways/service_test.go +++ b/control-plane/gateways/service_test.go @@ -15,7 +15,7 @@ import ( meshv2beta1 "github.com/hashicorp/consul-k8s/control-plane/api/mesh/v2beta1" ) -func Test_gatewayBuilder_meshGateway_Service(t *testing.T) { +func Test_meshGatewayBuilder_Service(t *testing.T) { lbType := corev1.ServiceTypeLoadBalancer type fields struct { @@ -144,7 +144,7 @@ func Test_gatewayBuilder_meshGateway_Service(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - b := &gatewayBuilder[*meshv2beta1.MeshGateway]{ + b := &meshGatewayBuilder{ gateway: tt.fields.gateway, config: tt.fields.config, gcc: tt.fields.gcc, @@ -216,143 +216,3 @@ func Test_MergeService(t *testing.T) { }) } } - -func Test_gatewayBuilder_apiGateway_Service(t *testing.T) { - lbType := corev1.ServiceTypeLoadBalancer - - type fields struct { - gateway *meshv2beta1.APIGateway - config GatewayConfig - gcc *meshv2beta1.GatewayClassConfig - } - tests := []struct { - name string - fields fields - want *corev1.Service - }{ - { - name: "service resource crd created - happy path", - fields: fields{ - gateway: &meshv2beta1.APIGateway{ - Spec: pbmesh.APIGateway{ - GatewayClassName: "test-gateway-class", - Listeners: []*pbmesh.APIGatewayListener{ - { - Name: "http-listener", - Port: 80, - Protocol: "http", - }, - }, - }, - }, - config: GatewayConfig{}, - gcc: &meshv2beta1.GatewayClassConfig{ - Spec: meshv2beta1.GatewayClassConfigSpec{ - GatewayClassAnnotationsAndLabels: meshv2beta1.GatewayClassAnnotationsAndLabels{ - Labels: meshv2beta1.GatewayClassAnnotationsLabelsConfig{ - Set: map[string]string{ - "app": "consul", - "chart": "consul-helm", - "heritage": "Helm", - "release": "consul", - }, - }, - }, - Deployment: meshv2beta1.GatewayClassDeploymentConfig{ - Container: &meshv2beta1.GatewayClassContainerConfig{ - PortModifier: 8000, - }, - }, - Service: meshv2beta1.GatewayClassServiceConfig{ - Type: &lbType, - }, - }, - }, - }, - want: &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{ - labelManagedBy: "consul-k8s", - "app": "consul", - "chart": "consul-helm", - "heritage": "Helm", - "release": "consul", - }, - Annotations: map[string]string{}, - }, - Spec: corev1.ServiceSpec{ - Selector: map[string]string{ - labelManagedBy: "consul-k8s", - "app": "consul", - "chart": "consul-helm", - "heritage": "Helm", - "release": "consul", - }, - Type: corev1.ServiceTypeLoadBalancer, - Ports: []corev1.ServicePort{ - { - Name: "http-listener", - Port: int32(80), - TargetPort: intstr.IntOrString{ - IntVal: int32(8080), - }, - Protocol: "http", - }, - }, - }, - Status: corev1.ServiceStatus{}, - }, - }, - { - name: "create service resource crd - gcc is nil", - fields: fields{ - gateway: &meshv2beta1.APIGateway{ - Spec: pbmesh.APIGateway{ - GatewayClassName: "test-gateway-class", - Listeners: []*pbmesh.APIGatewayListener{ - { - Name: "http-listener", - Port: 80, - Protocol: "http", - }, - }, - }, - }, - config: GatewayConfig{}, - gcc: nil, - }, - want: &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Labels: defaultLabels, - Annotations: map[string]string{}, - }, - Spec: corev1.ServiceSpec{ - Selector: defaultLabels, - Type: "", - Ports: []corev1.ServicePort{ - { - Name: "http-listener", - Port: int32(80), - TargetPort: intstr.IntOrString{ - IntVal: int32(80), - }, - Protocol: "http", - }, - }, - }, - Status: corev1.ServiceStatus{}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - b := &gatewayBuilder[*meshv2beta1.APIGateway]{ - gateway: tt.fields.gateway, - config: tt.fields.config, - gcc: tt.fields.gcc, - } - result := b.Service() - assert.Equalf(t, tt.want, result, "Service()") - }) - } -} diff --git a/control-plane/gateways/serviceaccount.go b/control-plane/gateways/serviceaccount.go index 8b740cbd76..1a0b32c275 100644 --- a/control-plane/gateways/serviceaccount.go +++ b/control-plane/gateways/serviceaccount.go @@ -8,17 +8,17 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -func (b *gatewayBuilder[T]) ServiceAccount() *corev1.ServiceAccount { +func (b *meshGatewayBuilder) ServiceAccount() *corev1.ServiceAccount { return &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: b.serviceAccountName(), - Namespace: b.gateway.GetNamespace(), + Namespace: b.gateway.Namespace, Labels: b.labelsForServiceAccount(), Annotations: b.annotationsForServiceAccount(), }, } } -func (b *gatewayBuilder[T]) serviceAccountName() string { - return b.gateway.GetName() +func (b *meshGatewayBuilder) serviceAccountName() string { + return b.gateway.Name } diff --git a/control-plane/gateways/serviceaccount_test.go b/control-plane/gateways/serviceaccount_test.go index 3f6fa6f24f..ff0fb4e878 100644 --- a/control-plane/gateways/serviceaccount_test.go +++ b/control-plane/gateways/serviceaccount_test.go @@ -14,7 +14,7 @@ import ( ) func TestNewMeshGatewayBuilder_ServiceAccount(t *testing.T) { - b := NewGatewayBuilder(&meshv2beta1.MeshGateway{ + b := NewMeshGatewayBuilder(&meshv2beta1.MeshGateway{ ObjectMeta: metav1.ObjectMeta{ Namespace: "default", Name: "mesh-gateway", diff --git a/control-plane/go.mod b/control-plane/go.mod index 5fa2475682..224f1b2386 100644 --- a/control-plane/go.mod +++ b/control-plane/go.mod @@ -2,7 +2,7 @@ module github.com/hashicorp/consul-k8s/control-plane // TODO: Remove this when the next version of the submodule is released. // We need to use a replace directive instead of directly pinning because `api` requires version `0.5.1` and will clobber the pin, but not the replace directive. -replace github.com/hashicorp/consul/proto-public => github.com/hashicorp/consul/proto-public v0.1.2-0.20240207215339-2456fe5148bd +replace github.com/hashicorp/consul/proto-public => github.com/hashicorp/consul/proto-public v0.1.2-0.20240208173503-e72afa654d22 replace github.com/hashicorp/consul/sdk => github.com/hashicorp/consul/sdk v0.4.1-0.20231213150639-123bc95e1a3f diff --git a/control-plane/go.sum b/control-plane/go.sum index 62f29b4bcd..c6c85880f5 100644 --- a/control-plane/go.sum +++ b/control-plane/go.sum @@ -265,8 +265,8 @@ github.com/hashicorp/consul-server-connection-manager v0.1.6 h1:ktj8Fi+dRXn9hhM+ github.com/hashicorp/consul-server-connection-manager v0.1.6/go.mod h1:HngMIv57MT+pqCVeRQMa1eTB5dqnyMm8uxjyv+Hn8cs= github.com/hashicorp/consul/api v1.10.1-0.20240122152324-758ddf84e9c9 h1:qaS6rE768dt5hGPl2y4DIABXF4eA23BNSmWFpEr3kWQ= github.com/hashicorp/consul/api v1.10.1-0.20240122152324-758ddf84e9c9/go.mod h1:gInwZGrnWlE1Vvq6rSD5pUf6qwNa69NTLLknbdwQRUk= -github.com/hashicorp/consul/proto-public v0.1.2-0.20240207215339-2456fe5148bd h1:xNTNL7j7qNNhH68bxHabcsS3GKL6T1OEMYDbbxJ42qI= -github.com/hashicorp/consul/proto-public v0.1.2-0.20240207215339-2456fe5148bd/go.mod h1:JF6983XNCzvw4wDNOLEwLqOq2IPw7iyT+pkswHSz08U= +github.com/hashicorp/consul/proto-public v0.1.2-0.20240208173503-e72afa654d22 h1:PQQfwXeitSSyeXffKDTB/pOpxOKodgXEiNYcEFpgEMI= +github.com/hashicorp/consul/proto-public v0.1.2-0.20240208173503-e72afa654d22/go.mod h1:JF6983XNCzvw4wDNOLEwLqOq2IPw7iyT+pkswHSz08U= github.com/hashicorp/consul/sdk v0.4.1-0.20231213150639-123bc95e1a3f h1:GKsa7bfoL7xgvCkzYJMF9eYYNfLWQyk8QuRZZl4nMTo= github.com/hashicorp/consul/sdk v0.4.1-0.20231213150639-123bc95e1a3f/go.mod h1:r/OmRRPbHOe0yxNahLw7G9x5WG17E1BIECMtCjcPSNo= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= diff --git a/control-plane/subcommand/inject-connect/v2controllers.go b/control-plane/subcommand/inject-connect/v2controllers.go index 13f83a12cc..79f8223fae 100644 --- a/control-plane/subcommand/inject-connect/v2controllers.go +++ b/control-plane/subcommand/inject-connect/v2controllers.go @@ -200,11 +200,6 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage return err } - if err := resourceControllers.RegisterGatewayFieldIndexes(ctx, mgr); err != nil { - setupLog.Error(err, "unable to register field indexes") - return err - } - if err := (&resourceControllers.MeshConfigurationController{ Controller: consulResourceController, Client: mgr.GetClient(), @@ -245,16 +240,6 @@ func (c *Command) configureV2Controllers(ctx context.Context, mgr manager.Manage return err } - if err := (&resourceControllers.APIGatewayController{ - Controller: consulResourceController, - Client: mgr.GetClient(), - Log: ctrl.Log.WithName("controller").WithName(common.APIGateway), - Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { - setupLog.Error(err, "unable to create controller", "controller", common.APIGateway) - return err - } - if err := (&resourceControllers.GatewayClassConfigController{ Controller: consulResourceController, Client: mgr.GetClient(), diff --git a/control-plane/subcommand/mesh-init/command_test.go b/control-plane/subcommand/mesh-init/command_test.go index 3567b36102..22184f5969 100644 --- a/control-plane/subcommand/mesh-init/command_test.go +++ b/control-plane/subcommand/mesh-init/command_test.go @@ -88,10 +88,10 @@ func TestRun_MeshServices(t *testing.T) { } for _, tt := range cases { t.Run(tt.name, func(t *testing.T) { - //tokenFile := fmt.Sprintf("/tmp/%d1", rand.Int()) - //t.Cleanup(func() { + // tokenFile := fmt.Sprintf("/tmp/%d1", rand.Int()) + // t.Cleanup(func() { // _ = os.RemoveAll(tokenFile) - //}) + // }) // Create test consulServer server. var serverCfg *testutil.TestServerConfig @@ -117,11 +117,11 @@ func TestRun_MeshServices(t *testing.T) { "-http-port", strconv.Itoa(serverCfg.Ports.HTTP), "-grpc-port", strconv.Itoa(serverCfg.Ports.GRPC), } - //if tt.aclsEnabled { + // if tt.aclsEnabled { // flags = append(flags, "-auth-method-name", test.AuthMethod, // "-service-account-name", tt.serviceAccountName, // "-acl-token-sink", tokenFile) //TODO: what happens if this is unspecified? We don't need this file - //} + // } // Run the command. code := cmd.Run(flags) @@ -133,7 +133,7 @@ func TestRun_MeshServices(t *testing.T) { // TODO: Can we remove the tokenFile from this workflow? // consul-dataplane performs it's own login using the Serviceaccount bearer token - //if tt.aclsEnabled { + // if tt.aclsEnabled { // // Validate the ACL token was written. // tokenData, err := os.ReadFile(tokenFile) // require.NoError(t, err) @@ -145,7 +145,7 @@ func TestRun_MeshServices(t *testing.T) { // token, _, err := consulClient.ACL().TokenReadSelf(nil) // require.NoError(t, err) // require.Equal(t, "token created via login: {\"pod\":\"default-ns/counting-pod\"}", token.Description) - //} + // } }) } } diff --git a/control-plane/version/version.go b/control-plane/version/version.go index f68d1632a6..da2c79a1b4 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.5.0" + Version = "1.4.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