diff --git a/.changelog/19218.txt b/.changelog/19218.txt deleted file mode 100644 index a3dde32317b47..0000000000000 --- a/.changelog/19218.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:improvement -resource: lowercase names enforced for v2 resources only. -``` \ No newline at end of file diff --git a/.changelog/19306.txt b/.changelog/19274.txt similarity index 100% rename from .changelog/19306.txt rename to .changelog/19274.txt diff --git a/.changelog/19311.txt b/.changelog/19311.txt deleted file mode 100644 index e53536f44d32b..0000000000000 --- a/.changelog/19311.txt +++ /dev/null @@ -1,3 +0,0 @@ -```release-note:bug -raft: Fix panic during downgrade from enterprise to oss. -``` \ No newline at end of file diff --git a/.github/workflows/nightly-test-1.17.x.yaml b/.github/workflows/nightly-test-1.13.x.yaml similarity index 96% rename from .github/workflows/nightly-test-1.17.x.yaml rename to .github/workflows/nightly-test-1.13.x.yaml index 9a063001e402c..f314a475dfbd7 100644 --- a/.github/workflows/nightly-test-1.17.x.yaml +++ b/.github/workflows/nightly-test-1.13.x.yaml @@ -1,7 +1,7 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: MPL-2.0 -name: Nightly Frontend Test 1.17.x +name: Nightly Frontend Test 1.13.x on: schedule: - cron: '0 4 * * *' @@ -9,8 +9,8 @@ on: env: EMBER_PARTITION_TOTAL: 4 # Has to be changed in tandem with the matrix.partition - BRANCH: "release/1.17.x" - BRANCH_NAME: "release-1.17.x" # Used for naming artifacts + BRANCH: "release/1.13.x" + BRANCH_NAME: "release-1.13.x" # Used for naming artifacts GOPRIVATE: github.com/hashicorp # Required for enterprise deps jobs: @@ -24,7 +24,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -56,7 +56,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -95,7 +95,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -128,7 +128,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -167,7 +167,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock @@ -198,7 +198,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: 18 + node-version: 14 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock diff --git a/.github/workflows/nightly-test-integrations-1.17.x.yml b/.github/workflows/nightly-test-integrations-1.17.x.yml deleted file mode 100644 index 660a28374b783..0000000000000 --- a/.github/workflows/nightly-test-integrations-1.17.x.yml +++ /dev/null @@ -1,342 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: MPL-2.0 - -name: Nightly test-integrations 1.17.x - -on: - schedule: - # Run nightly at 1AM UTC/9PM EST/6PM PST - - cron: '* 1 * * *' - workflow_dispatch: {} - -env: - TEST_RESULTS_DIR: /tmp/test-results - TEST_RESULTS_ARTIFACT_NAME: test-results - CONSUL_LICENSE: ${{ secrets.CONSUL_LICENSE }} - GOTAGS: ${{ endsWith(github.repository, '-enterprise') && 'consulent' || '' }} - GOTESTSUM_VERSION: "1.10.1" - CONSUL_BINARY_UPLOAD_NAME: consul-bin - # strip the hashicorp/ off the front of github.repository for consul - CONSUL_LATEST_IMAGE_NAME: ${{ endsWith(github.repository, '-enterprise') && github.repository || 'hashicorp/consul' }} - GOPRIVATE: github.com/hashicorp # Required for enterprise deps - BRANCH: "release/1.17.x" - BRANCH_NAME: "release-1.17.x" # Used for naming artifacts - -jobs: - setup: - runs-on: ubuntu-latest - name: Setup - outputs: - compute-small: ${{ steps.runners.outputs.compute-small }} - compute-medium: ${{ steps.runners.outputs.compute-medium }} - compute-large: ${{ steps.runners.outputs.compute-large }} - compute-xl: ${{ steps.runners.outputs.compute-xl }} - enterprise: ${{ steps.runners.outputs.enterprise }} - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - id: runners - run: .github/scripts/get_runner_classes.sh - - dev-build: - needs: [setup] - uses: ./.github/workflows/reusable-dev-build.yml - with: - runs-on: ${{ needs.setup.outputs.compute-large }} - repository-name: ${{ github.repository }} - uploaded-binary-name: 'consul-bin' - branch-name: "release/1.17.x" - secrets: - elevated-github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }} - - generate-envoy-job-matrices: - needs: [setup] - runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - name: Generate Envoy Job Matrices - outputs: - envoy-matrix: ${{ steps.set-matrix.outputs.envoy-matrix }} - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - name: Generate Envoy Job Matrix - id: set-matrix - env: - # this is further going to multiplied in envoy-integration tests by the - # other dimensions in the matrix. Currently TOTAL_RUNNERS would be - # multiplied by 8 based on these values: - # envoy-version: ["1.24.12", "1.25.11", "1.26.6", "1.27.2"] - # xds-target: ["server", "client"] - TOTAL_RUNNERS: 4 - JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' - run: | - NUM_RUNNERS=$TOTAL_RUNNERS - NUM_DIRS=$(find ./test/integration/connect/envoy -mindepth 1 -maxdepth 1 -type d | wc -l) - - if [ "$NUM_DIRS" -lt "$NUM_RUNNERS" ]; then - echo "TOTAL_RUNNERS is larger than the number of tests/packages to split." - NUM_RUNNERS=$((NUM_DIRS-1)) - fi - # fix issue where test splitting calculation generates 1 more split than TOTAL_RUNNERS. - NUM_RUNNERS=$((NUM_RUNNERS-1)) - { - echo -n "envoy-matrix=" - find ./test/integration/connect/envoy -maxdepth 1 -type d -print0 \ - | xargs -0 -n 1 basename \ - | jq --raw-input --argjson runnercount "$NUM_RUNNERS" "$JQ_SLICER" \ - | jq --compact-output 'map(join("|"))' - } >> "$GITHUB_OUTPUT" - - envoy-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - needs: - - setup - - generate-envoy-job-matrices - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - envoy-version: ["1.24.12", "1.25.11", "1.26.6", "1.27.2"] - xds-target: ["server", "client"] - test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} - env: - ENVOY_VERSION: ${{ matrix.envoy-version }} - XDS_TARGET: ${{ matrix.xds-target }} - AWS_LAMBDA_REGION: us-west-2 - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: ./bin - - name: restore mode+x - run: chmod +x ./bin/consul - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@2a1a44ac4aa01993040736bd95bb470da1a38365 # v2.9.0 - - - name: Docker build - run: docker build -t consul:local -f ./build-support/docker/Consul-Dev.dockerfile ./bin - - - name: Envoy Integration Tests - env: - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - LAMBDA_TESTS_ENABLED: "true" - # tput complains if this isn't set to something. - TERM: ansi - run: | - # shellcheck disable=SC2001 - echo "Running $(sed 's,|, ,g' <<< "${{ matrix.test-cases }}" |wc -w) subtests" - # shellcheck disable=SC2001 - sed 's,|,\n,g' <<< "${{ matrix.test-cases }}" - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --debug \ - --rerun-fails \ - --rerun-fails-report=/tmp/gotestsum-rerun-fails \ - --jsonfile /tmp/jsonfile/go-test.log \ - --packages=./test/integration/connect/envoy \ - -- -timeout=30m -tags integration -run="TestEnvoy/(${{ matrix.test-cases }})" - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - upgrade-integration-test: - runs-on: ${{ fromJSON(needs.setup.outputs.compute-large) }} - needs: - - setup - - dev-build - permissions: - id-token: write # NOTE: this permission is explicitly required for Vault auth. - contents: read - strategy: - fail-fast: false - matrix: - consul-version: ["1.15", "1.16", "1.17"] - env: - CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.24.6" - steps: - - name: Checkout code - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - ref: ${{ env.BRANCH }} - # NOTE: This step is specifically needed for ENT. It allows us to access the required private HashiCorp repos. - - name: Setup Git - if: ${{ endsWith(github.repository, '-enterprise') }} - run: git config --global url."https://${{ secrets.ELEVATED_GITHUB_TOKEN }}:@github.com".insteadOf "https://github.com" - - uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753 # v4.0.1 - with: - go-version-file: 'go.mod' - - run: go env - - # Get go binary from workspace - - name: fetch binary - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 - with: - name: '${{ env.CONSUL_BINARY_UPLOAD_NAME }}' - path: . - - name: restore mode+x - run: chmod +x consul - - name: Build consul:local image - run: docker build -t ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local -f ./build-support/docker/Consul-Dev.dockerfile . - - name: Build consul-envoy:latest-version image - id: buildConsulEnvoyLatestImage - run: | - if ${{ endsWith(github.repository, '-enterprise') }} == 'true' - then - docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }}-ent --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - else - docker build -t consul-envoy:latest-version --build-arg CONSUL_IMAGE=docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }}:${{ env.CONSUL_LATEST_VERSION }} --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - fi - - name: Build consul-envoy:target-version image - id: buildConsulEnvoyTargetImage - continue-on-error: true - run: docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=${{ env.CONSUL_LATEST_IMAGE_NAME }}:local --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - - name: Retry Build consul-envoy:target-version image - if: steps.buildConsulEnvoyTargetImage.outcome == 'failure' - run: docker build -t consul-envoy:target-version --build-arg CONSUL_IMAGE=${{ env.CONSUL_LATEST_IMAGE_NAME }}:local --build-arg ENVOY_VERSION=${{ env.ENVOY_VERSION }} -f ./test/integration/consul-container/assets/Dockerfile-consul-envoy ./test/integration/consul-container/assets - - name: Build sds image - run: docker build -t consul-sds-server ./test/integration/connect/envoy/test-sds-server/ - - name: Configure GH workaround for ipv6 loopback - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - cat /etc/hosts && echo "-----------" - sudo sed -i 's/::1 *localhost ip6-localhost ip6-loopback/::1 ip6-localhost ip6-loopback/g' /etc/hosts - cat /etc/hosts - - name: Upgrade Integration Tests - run: | - mkdir -p "${{ env.TEST_RESULTS_DIR }}" - cd ./test/integration/consul-container/test/upgrade - docker run --rm ${{ env.CONSUL_LATEST_IMAGE_NAME }}:local consul version - go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ - --raw-command \ - --format=short-verbose \ - --debug \ - --rerun-fails=2 \ - --packages="./..." \ - -- \ - go test \ - -p=4 \ - -tags "${{ env.GOTAGS }}" \ - -timeout=30m \ - -json \ - ./... \ - --follow-log=false \ - --target-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --target-version local \ - --latest-image docker.mirror.hashicorp.services/${{ env.CONSUL_LATEST_IMAGE_NAME }} \ - --latest-version "${{ env.CONSUL_LATEST_VERSION }}" - ls -lrt - env: - # this is needed because of incompatibility between RYUK container and GHA - GOTESTSUM_JUNITFILE: ${{ env.TEST_RESULTS_DIR }}/results.xml - GOTESTSUM_FORMAT: standard-verbose - COMPOSE_INTERACTIVE_NO_CLI: 1 - # tput complains if this isn't set to something. - TERM: ansi - # NOTE: ENT specific step as we store secrets in Vault. - - name: Authenticate to Vault - if: ${{ endsWith(github.repository, '-enterprise') }} - id: vault-auth - run: vault-auth - - # NOTE: ENT specific step as we store secrets in Vault. - - name: Fetch Secrets - if: ${{ endsWith(github.repository, '-enterprise') }} - id: secrets - uses: hashicorp/vault-action@v2.5.0 - with: - url: ${{ steps.vault-auth.outputs.addr }} - caCertificate: ${{ steps.vault-auth.outputs.ca_certificate }} - token: ${{ steps.vault-auth.outputs.token }} - secrets: | - kv/data/github/${{ github.repository }}/datadog apikey | DATADOG_API_KEY; - - - name: prepare datadog-ci - if: ${{ !endsWith(github.repository, '-enterprise') }} - run: | - curl -L --fail "https://github.com/DataDog/datadog-ci/releases/latest/download/datadog-ci_linux-x64" --output "/usr/local/bin/datadog-ci" - chmod +x /usr/local/bin/datadog-ci - - - name: upload coverage - # do not run on forks - if: github.event.pull_request.head.repo.full_name == github.repository - env: - DATADOG_API_KEY: "${{ endsWith(github.repository, '-enterprise') && env.DATADOG_API_KEY || secrets.DATADOG_API_KEY }}" - DD_ENV: ci - run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml - - - test-integrations-success: - needs: - - setup - - dev-build - - generate-envoy-job-matrices - - envoy-integration-test - - upgrade-integration-test - runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} - if: ${{ always() }} - steps: - - name: evaluate upstream job results - run: | - # exit 1 if failure or cancelled result for any upstream job - if printf '${{ toJSON(needs) }}' | grep -E -i '\"result\": \"(failure|cancelled)\"'; then - printf "Tests failed or workflow cancelled:\n\n${{ toJSON(needs) }}" - exit 1 - fi - - name: Notify Slack - if: ${{ failure() }} - id: slack - uses: slackapi/slack-github-action@e28cf165c92ffef168d23c5c9000cffc8a25e117 # v1.24.0 - with: - payload: | - { - "message": "One or more nightly integration tests have failed on branch ${{ env.BRANCH }} for Consul. ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.CONSUL_NIGHTLY_INTEG_TEST_SLACK_WEBHOOK }} diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index bab962f23eaae..a350ca1e7db26 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -193,10 +193,10 @@ jobs: strategy: fail-fast: false matrix: - consul-version: [ "1.16", "1.17"] + consul-version: [ "1.15", "1.16", "1.17"] env: CONSUL_LATEST_VERSION: ${{ matrix.consul-version }} - ENVOY_VERSION: "1.25.4" + ENVOY_VERSION: "1.24.6" steps: - name: Checkout code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/reusable-unit-split.yml b/.github/workflows/reusable-unit-split.yml index 3d959d168beda..29c341998dd65 100644 --- a/.github/workflows/reusable-unit-split.yml +++ b/.github/workflows/reusable-unit-split.yml @@ -130,8 +130,7 @@ jobs: --packages="$PACKAGE_NAMES" \ --junitfile ${{env.TEST_RESULTS}}/gotestsum-report.xml -- \ -tags="${{env.GOTAGS}}" \ - -cover -coverprofile=coverage.txt \ - -timeout=30m + -cover -coverprofile=coverage.txt # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault diff --git a/.github/workflows/reusable-unit.yml b/.github/workflows/reusable-unit.yml index 3b50bfa7e3887..42943954475d3 100644 --- a/.github/workflows/reusable-unit.yml +++ b/.github/workflows/reusable-unit.yml @@ -109,8 +109,7 @@ jobs: --junitfile ${{env.TEST_RESULTS}}/gotestsum-report.xml -- \ -tags="${{env.GOTAGS}}" \ ${GO_TEST_FLAGS-} \ - -cover -coverprofile=coverage.txt \ - -timeout=30m + -cover -coverprofile=coverage.txt # NOTE: ENT specific step as we store secrets in Vault. - name: Authenticate to Vault diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 980ea3d26cded..86b8741af7159 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -81,6 +81,7 @@ jobs: strategy: matrix: nomad-version: ['v1.6.2', 'v1.5.9', 'v1.4.13'] + steps: - name: Checkout Nomad uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 diff --git a/.github/workflows/verify-envoy-version.yml b/.github/workflows/verify-envoy-version.yml index dafa9db6f22a6..003888eddf6e1 100644 --- a/.github/workflows/verify-envoy-version.yml +++ b/.github/workflows/verify-envoy-version.yml @@ -13,7 +13,7 @@ on: branches: - main - release/** - + env: SKIP_VERIFY_ENVOY_VERSION: ${{ vars.SKIP_VERIFY_ENVOY_VERSION }} diff --git a/README.md b/README.md index c23053f0e1f7d..870e00f76c761 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,6 @@ Consul provides several key features: can use sidecar proxies in a service mesh configuration to establish TLS connections for inbound and outbound connections with Transparent Proxy. -* **API Gateway** - Consul API Gateway manages access to services within Consul Service Mesh, - allow users to define traffic and authorization policies to services deployed within the mesh. - * **Service Discovery** - Consul makes it simple for services to register themselves and to discover other services via a DNS or HTTP interface. External services such as SaaS providers can be registered as well. diff --git a/agent/consul/fsm/commands_ce.go b/agent/consul/fsm/commands_ce.go index 77bc94de1a9ae..c5e7fd968238b 100644 --- a/agent/consul/fsm/commands_ce.go +++ b/agent/consul/fsm/commands_ce.go @@ -4,7 +4,6 @@ package fsm import ( - "errors" "fmt" "time" @@ -153,11 +152,7 @@ func init() { func (c *FSM) applyRegister(buf []byte, index uint64) interface{} { defer metrics.MeasureSince([]string{"fsm", "register"}, time.Now()) var req structs.RegisterRequest - if err := decodeRegistrationReq(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted register request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } @@ -172,11 +167,7 @@ func (c *FSM) applyRegister(buf []byte, index uint64) interface{} { func (c *FSM) applyDeregister(buf []byte, index uint64) interface{} { defer metrics.MeasureSince([]string{"fsm", "deregister"}, time.Now()) var req structs.DeregisterRequest - if err := decodeDeregistrationReq(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted deregister request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } @@ -204,11 +195,7 @@ func (c *FSM) applyDeregister(buf []byte, index uint64) interface{} { func (c *FSM) applyKVSOperation(buf []byte, index uint64) interface{} { var req structs.KVSRequest - if err := decodeKVSRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted KV request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "kvs"}, time.Now(), @@ -253,11 +240,7 @@ func (c *FSM) applyKVSOperation(buf []byte, index uint64) interface{} { func (c *FSM) applySessionOperation(buf []byte, index uint64) interface{} { var req structs.SessionRequest - if err := decodeSessionRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted session request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "session"}, time.Now(), @@ -316,11 +299,7 @@ func (c *FSM) applyCoordinateBatchUpdate(buf []byte, index uint64) interface{} { // state store. func (c *FSM) applyPreparedQueryOperation(buf []byte, index uint64) interface{} { var req structs.PreparedQueryRequest - if err := decodePreparedQueryRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted prepared query request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } @@ -339,7 +318,7 @@ func (c *FSM) applyPreparedQueryOperation(buf []byte, index uint64) interface{} func (c *FSM) applyTxn(buf []byte, index uint64) interface{} { var req structs.TxnRequest - if err := decodeTxnRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSince([]string{"fsm", "txn"}, time.Now()) @@ -506,7 +485,7 @@ func (c *FSM) applyConnectCALeafOperation(buf []byte, index uint64) interface{} func (c *FSM) applyACLTokenSetOperation(buf []byte, index uint64) interface{} { var req structs.ACLTokenBatchSetRequest - if err := decodeACLTokenBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "token"}, time.Now(), @@ -544,7 +523,7 @@ func (c *FSM) applyACLTokenBootstrap(buf []byte, index uint64) interface{} { func (c *FSM) applyACLPolicySetOperation(buf []byte, index uint64) interface{} { var req structs.ACLPolicyBatchSetRequest - if err := decodeACLPolicyBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "policy"}, time.Now(), @@ -565,12 +544,10 @@ func (c *FSM) applyACLPolicyDeleteOperation(buf []byte, index uint64) interface{ } func (c *FSM) applyConfigEntryOperation(buf []byte, index uint64) interface{} { - req := structs.ConfigEntryRequest{} - if err := decodeConfigEntryOperationRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted config entry request") - return nil - } + req := structs.ConfigEntryRequest{ + Entry: &structs.ProxyConfigEntry{}, + } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } @@ -617,7 +594,7 @@ func (c *FSM) applyConfigEntryOperation(buf []byte, index uint64) interface{} { func (c *FSM) applyACLRoleSetOperation(buf []byte, index uint64) interface{} { var req structs.ACLRoleBatchSetRequest - if err := decodeACLRoleBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "role"}, time.Now(), @@ -639,7 +616,7 @@ func (c *FSM) applyACLRoleDeleteOperation(buf []byte, index uint64) interface{} func (c *FSM) applyACLBindingRuleSetOperation(buf []byte, index uint64) interface{} { var req structs.ACLBindingRuleBatchSetRequest - if err := decodeACLBindingRuleBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "bindingrule"}, time.Now(), @@ -661,7 +638,7 @@ func (c *FSM) applyACLBindingRuleDeleteOperation(buf []byte, index uint64) inter func (c *FSM) applyACLAuthMethodSetOperation(buf []byte, index uint64) interface{} { var req structs.ACLAuthMethodBatchSetRequest - if err := decodeACLAuthMethodBatchSetRequest(buf, &req); err != nil { + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "authmethod"}, time.Now(), @@ -672,11 +649,7 @@ func (c *FSM) applyACLAuthMethodSetOperation(buf []byte, index uint64) interface func (c *FSM) applyACLAuthMethodDeleteOperation(buf []byte, index uint64) interface{} { var req structs.ACLAuthMethodBatchDeleteRequest - if err := decodeACLAuthMethodBatchDeleteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted acl auth method delete request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } defer metrics.MeasureSinceWithLabels([]string{"fsm", "acl", "authmethod"}, time.Now(), @@ -733,11 +706,7 @@ func (c *FSM) applySystemMetadataOperation(buf []byte, index uint64) interface{} func (c *FSM) applyPeeringWrite(buf []byte, index uint64) interface{} { var req pbpeering.PeeringWriteRequest - if err := decodePeeringWriteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted peering write request") - return nil - } + if err := structs.DecodeProto(buf, &req); err != nil { panic(fmt.Errorf("failed to decode peering write request: %v", err)) } @@ -749,11 +718,7 @@ func (c *FSM) applyPeeringWrite(buf []byte, index uint64) interface{} { func (c *FSM) applyPeeringDelete(buf []byte, index uint64) interface{} { var req pbpeering.PeeringDeleteRequest - if err := decodePeeringDeleteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted peering delete request") - return nil - } + if err := structs.DecodeProto(buf, &req); err != nil { panic(fmt.Errorf("failed to decode peering delete request: %v", err)) } @@ -793,11 +758,7 @@ func (c *FSM) applyPeeringTerminate(buf []byte, index uint64) interface{} { func (c *FSM) applyPeeringTrustBundleWrite(buf []byte, index uint64) interface{} { var req pbpeering.PeeringTrustBundleWriteRequest - if err := decodePeeringTrustBundleWriteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted peering trust bundle write request") - return nil - } + if err := structs.DecodeProto(buf, &req); err != nil { panic(fmt.Errorf("failed to decode peering trust bundle write request: %v", err)) } @@ -809,11 +770,7 @@ func (c *FSM) applyPeeringTrustBundleWrite(buf []byte, index uint64) interface{} func (c *FSM) applyPeeringTrustBundleDelete(buf []byte, index uint64) interface{} { var req pbpeering.PeeringTrustBundleDeleteRequest - if err := decodePeeringTrustBundleDeleteRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted peering trust bundle delete request") - return nil - } + if err := structs.DecodeProto(buf, &req); err != nil { panic(fmt.Errorf("failed to decode peering trust bundle delete request: %v", err)) } @@ -833,11 +790,7 @@ func (f *FSM) applyResourceOperation(buf []byte, idx uint64) any { func (c *FSM) applyManualVirtualIPs(buf []byte, index uint64) interface{} { var req state.ServiceVirtualIP - if err := decodeServiceVirtualIPRequest(buf, &req); err != nil { - if errors.Is(err, ErrDroppingTenantedReq) { - c.logger.Warn("dropping tenanted virtual ip request") - return nil - } + if err := structs.Decode(buf, &req); err != nil { panic(fmt.Errorf("failed to decode request: %v", err)) } diff --git a/agent/consul/fsm/decode_ce.go b/agent/consul/fsm/decode_ce.go deleted file mode 100644 index 2f4d3da3a26cb..0000000000000 --- a/agent/consul/fsm/decode_ce.go +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent -// +build !consulent - -package fsm - -import ( - "github.com/hashicorp/consul/agent/consul/state" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/proto/private/pbpeering" -) - -func decodeRegistrationReq(buf []byte, req *structs.RegisterRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeRegistration(buf, req) -} - -func decodeDeregistrationReq(buf []byte, req *structs.DeregisterRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeDeregistration(buf, req) -} - -func decodeKVSRequest(buf []byte, req *structs.KVSRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeKVS(buf, req) -} - -func decodeSessionRequest(buf []byte, req *structs.SessionRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - - return decodeSession(buf, req) -} - -func decodePreparedQueryRequest(buf []byte, req *structs.PreparedQueryRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodePreparedQuery(buf, req) -} - -func decodeTxnRequest(buf []byte, req *structs.TxnRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeTxn(buf, req) -} - -func decodeACLTokenBatchSetRequest(buf []byte, req *structs.ACLTokenBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLTokenBatchSet(buf, req) - -} - -func decodeACLPolicyBatchSetRequest(buf []byte, req *structs.ACLPolicyBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLPolicyBatchSet(buf, req) - -} - -func decodeACLRoleBatchSetRequest(buf []byte, req *structs.ACLRoleBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLRoleBatchSet(buf, req) -} - -func decodeACLBindingRuleBatchSetRequest(buf []byte, req *structs.ACLBindingRuleBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLBindingRuleBatchSet(buf, req) -} - -func decodeACLAuthMethodBatchSetRequest(buf []byte, req *structs.ACLAuthMethodBatchSetRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeACLAuthMethodBatchSet(buf, req) -} - -func decodeACLAuthMethodBatchDeleteRequest(buf []byte, req *structs.ACLAuthMethodBatchDeleteRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - - return decodeACLAuthMethodBatchDelete(buf, req) -} - -func decodeServiceVirtualIPRequest(buf []byte, req *state.ServiceVirtualIP) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - return decodeServiceVirtualIP(buf, req) -} - -func decodePeeringWriteRequest(buf []byte, req *pbpeering.PeeringWriteRequest) error { - if !structs.CEDowngrade { - return structs.DecodeProto(buf, req) - } - return decodePeeringWrite(buf, req) -} - -func decodePeeringDeleteRequest(buf []byte, req *pbpeering.PeeringDeleteRequest) error { - if !structs.CEDowngrade { - return structs.DecodeProto(buf, req) - } - - return decodePeeringDelete(buf, req) -} - -func decodePeeringTrustBundleWriteRequest(buf []byte, req *pbpeering.PeeringTrustBundleWriteRequest) error { - if !structs.CEDowngrade { - return structs.DecodeProto(buf, req) - } - return decodePeeringTrustBundleWrite(buf, req) -} - -func decodePeeringTrustBundleDeleteRequest(buf []byte, req *pbpeering.PeeringTrustBundleDeleteRequest) error { - if !structs.CEDowngrade { - return structs.DecodeProto(buf, req) - } - return decodePeeringTrustBundleDelete(buf, req) -} - -func decodeConfigEntryOperationRequest(buf []byte, req *structs.ConfigEntryRequest) error { - if !structs.CEDowngrade { - return structs.Decode(buf, req) - } - - return decodeConfigEntryOperation(buf, req) -} diff --git a/agent/consul/fsm/decode_downgrade.go b/agent/consul/fsm/decode_downgrade.go deleted file mode 100644 index 7b8e2fce719f2..0000000000000 --- a/agent/consul/fsm/decode_downgrade.go +++ /dev/null @@ -1,1011 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package fsm - -import ( - "errors" - "fmt" - - "github.com/hashicorp/consul-net-rpc/go-msgpack/codec" - "github.com/hashicorp/consul/agent/consul/state" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/lib" - "github.com/hashicorp/consul/proto/private/pbpeering" -) - -func IsEnterpriseData(namespace, partition string) bool { - if (namespace != "" && namespace != "default") || (partition != "" && partition != "default") { - return true - } - return false -} - -var errIncompatibleTenantedData = errors.New("incompatible tenanted data") -var ErrDroppingTenantedReq = errors.New("dropping tenanted request") - -func decodeRegistration(buf []byte, req *structs.RegisterRequest) error { - type serviceRequest struct { - Namespace string - Partition string - *structs.NodeService - } - type checkRequest struct { - Namespace string - Partition string - *structs.HealthCheck - } - type NewRegReq struct { - - // shadows the Service field from the register request so that we can detect - // tenanted service registrations for untenanted nodes - Service *serviceRequest - - // shadows the Check field from the register request so that we can detect - // tenanted check registrations for untenanted nodes. - Check *checkRequest - - // shadows the Checks field for the same reasons as the singular version. - Checks []*checkRequest - - // Allows parsing the namespace of the whole request/node - Namespace string - - // Allows parsing the partition of the whole request/node - Partition string - *structs.RegisterRequest - } - var newReq NewRegReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - // checks if the node is tenanted - if IsEnterpriseData(newReq.Namespace, newReq.Partition) { - // the whole request can be dropped because the node itself is tenanted - return ErrDroppingTenantedReq - } - - // check if the service is tenanted - if newReq.Service != nil && !IsEnterpriseData(newReq.Service.Namespace, newReq.Service.Partition) { - // copy the shadow service pointer into the real RegisterRequest - newReq.RegisterRequest.Service = newReq.Service.NodeService - } - - // check if the singular check is tenanted - if newReq.Check != nil && !IsEnterpriseData(newReq.Check.Namespace, newReq.Check.Partition) { - newReq.RegisterRequest.Check = newReq.Check.HealthCheck - } - - // check for tenanted checks in the slice - for _, chk := range newReq.Checks { - if !IsEnterpriseData(chk.Namespace, chk.Partition) { - newReq.RegisterRequest.Checks = append(newReq.RegisterRequest.Checks, chk.HealthCheck) - } - } - // copy the data to the output request value - *req = *newReq.RegisterRequest - return nil -} - -func decodeDeregistration(buf []byte, req *structs.DeregisterRequest) error { - type NewDeRegReq struct { - Namespace string - - // Allows parsing the partition of the whole request/node - Partition string - - *structs.DeregisterRequest - - // Allows parsing the namespace of the whole request/node - - } - var newReq NewDeRegReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - // checks if the node is tenanted - if IsEnterpriseData(newReq.Namespace, newReq.Partition) { - // the whole request can be dropped because the node itself is tenanted - return ErrDroppingTenantedReq - } - - // copy the data to the output request value - *req = *newReq.DeregisterRequest - return nil -} - -func decodeKVS(buf []byte, req *structs.KVSRequest) error { - type dirEntryReq struct { - Namespace string - Partition string - *structs.DirEntry - } - type NewDirEntReq struct { - // shadows the DirEnt field from KVSRequest so that we can detect - // tenanted service registrations for untenanted nodes - DirEnt *dirEntryReq - *structs.KVSRequest - } - var newReq NewDirEntReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if newReq.DirEnt != nil && IsEnterpriseData(newReq.DirEnt.Namespace, newReq.DirEnt.Partition) { - return ErrDroppingTenantedReq - } - - newReq.KVSRequest.DirEnt = *newReq.DirEnt.DirEntry - *req = *newReq.KVSRequest - return nil -} - -func decodeSession(buf []byte, req *structs.SessionRequest) error { - type sessionReq struct { - Namespace string - Partition string - *structs.Session - } - type NewSessionReq struct { - // shadows the Session field from SessionRequest so that we can detect - // tenanted service registrations for untenanted nodes - Session *sessionReq - *structs.SessionRequest - } - var newReq NewSessionReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if newReq.Session != nil && IsEnterpriseData(newReq.Session.Namespace, newReq.Session.Partition) { - return ErrDroppingTenantedReq - - } - serviceChecks := newReq.Session.ServiceChecks - newReq.Session.ServiceChecks = nil - for _, sessionServiceCheck := range serviceChecks { - if !IsEnterpriseData(sessionServiceCheck.Namespace, "") { - newReq.Session.ServiceChecks = append(newReq.Session.ServiceChecks, sessionServiceCheck) - } - } - - newReq.SessionRequest.Session = *newReq.Session.Session - *req = *newReq.SessionRequest - return nil -} - -func decodePreparedQuery(buf []byte, req *structs.PreparedQueryRequest) error { - type serviceQuery struct { - Namespace string - Partition string - *structs.ServiceQuery - } - type prepQuery struct { - Service *serviceQuery - *structs.PreparedQuery - } - type NewPreparedQueryReq struct { - Query *prepQuery - *structs.PreparedQueryRequest - } - var newReq NewPreparedQueryReq - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if newReq.Query != nil && newReq.Query.Service != nil && IsEnterpriseData(newReq.Query.Service.Namespace, newReq.Query.Service.Partition) { - return ErrDroppingTenantedReq - } - - newReq.Query.PreparedQuery.Service = *newReq.Query.Service.ServiceQuery - newReq.PreparedQueryRequest.Query = newReq.Query.PreparedQuery - *req = *newReq.PreparedQueryRequest - return nil -} - -func decodeTxn(buf []byte, req *structs.TxnRequest) error { - type dirEntryReq struct { - Namespace string - Partition string - *structs.DirEntry - } - type txnKVOp struct { - DirEnt *dirEntryReq - *structs.TxnKVOp - } - type nodeService struct { - Namespace string - Partition string - *structs.NodeService - } - type txnServiceOp struct { - Service *nodeService - *structs.TxnServiceOp - } - type healthCheck struct { - Namespace string - Partition string - *structs.HealthCheck - } - type txnCheckOp struct { - Check *healthCheck - *structs.TxnCheckOp - } - type session struct { - Namespace string - Partition string - *structs.Session - } - type txnSessionOp struct { - Session *session - *structs.TxnSessionOp - } - // Only one of the types should be filled out per entry. - type txnOp struct { - KV *txnKVOp - Service *txnServiceOp - Check *txnCheckOp - Session *txnSessionOp - *structs.TxnOp - } - type NewTxnRequest struct { - Ops []*txnOp - *structs.TxnRequest - } - var newReq NewTxnRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - for _, op := range newReq.Ops { - if op.KV != nil && op.KV.DirEnt != nil && !IsEnterpriseData(op.KV.DirEnt.Namespace, op.KV.DirEnt.Partition) { - txnOp := &structs.TxnOp{ - KV: &structs.TxnKVOp{ - Verb: op.KV.Verb, - DirEnt: *op.KV.DirEnt.DirEntry, - }, - } - newReq.TxnRequest.Ops = append(newReq.TxnRequest.Ops, txnOp) - continue - } - - if op.Service != nil && op.Service.Service != nil && !IsEnterpriseData(op.Service.Service.Namespace, op.Service.Service.Partition) { - txnOp := &structs.TxnOp{ - Service: &structs.TxnServiceOp{ - Verb: op.Service.Verb, - Node: op.Service.Node, - Service: *op.Service.Service.NodeService, - }, - } - newReq.TxnRequest.Ops = append(newReq.TxnRequest.Ops, txnOp) - continue - } - - if op.Check != nil && op.Check.Check != nil && !IsEnterpriseData(op.Check.Check.Namespace, op.Check.Check.Partition) { - txnOp := &structs.TxnOp{ - Check: &structs.TxnCheckOp{ - Verb: op.Check.Verb, - Check: *op.Check.Check.HealthCheck, - }, - } - newReq.TxnRequest.Ops = append(newReq.TxnRequest.Ops, txnOp) - continue - } - - if op.Session != nil && op.Session.Session != nil && !IsEnterpriseData(op.Session.Session.Namespace, op.Session.Session.Partition) { - txnOp := &structs.TxnOp{ - Session: &structs.TxnSessionOp{ - Verb: op.Session.Verb, - Session: *op.Session.Session.Session, - }, - } - txnOp.Session.Session.ServiceChecks = nil - for _, sessionServiceCheck := range op.Session.Session.ServiceChecks { - if !IsEnterpriseData(sessionServiceCheck.Namespace, "") { - txnOp.Session.Session.ServiceChecks = append(txnOp.Session.Session.ServiceChecks, sessionServiceCheck) - } - } - newReq.TxnRequest.Ops = append(newReq.TxnRequest.Ops, txnOp) - } - } - - *req = *newReq.TxnRequest - return nil -} - -func decodeACLTokenBatchSet(buf []byte, req *structs.ACLTokenBatchSetRequest) error { - type aclToken struct { - Namespace string - Partition string - *structs.ACLToken - } - type NewACLTokenBatchSetRequest struct { - Tokens []*aclToken - *structs.ACLTokenBatchSetRequest - } - var newReq NewACLTokenBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - for _, token := range newReq.Tokens { - if !IsEnterpriseData(token.Namespace, token.Partition) { - newReq.ACLTokenBatchSetRequest.Tokens = append(newReq.ACLTokenBatchSetRequest.Tokens, token.ACLToken) - } - } - - *req = *newReq.ACLTokenBatchSetRequest - return nil - -} - -func decodeACLPolicyBatchSet(buf []byte, req *structs.ACLPolicyBatchSetRequest) error { - type aclPolicy struct { - Namespace string - Partition string - *structs.ACLPolicy - } - type NewACLPolicyBatchSetRequest struct { - Policies []*aclPolicy - *structs.ACLPolicyBatchSetRequest - } - var newReq NewACLPolicyBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - if newReq.ACLPolicyBatchSetRequest == nil { - newReq.ACLPolicyBatchSetRequest = &structs.ACLPolicyBatchSetRequest{} - } - for _, policy := range newReq.Policies { - if !IsEnterpriseData(policy.Namespace, policy.Partition) { - newReq.ACLPolicyBatchSetRequest.Policies = append(newReq.ACLPolicyBatchSetRequest.Policies, policy.ACLPolicy) - } - } - - *req = *newReq.ACLPolicyBatchSetRequest - return nil - -} - -func decodeACLRoleBatchSet(buf []byte, req *structs.ACLRoleBatchSetRequest) error { - type aclRole struct { - Namespace string - Partition string - *structs.ACLRole - } - type NewACLRoleBatchSetRequest struct { - Roles []*aclRole - *structs.ACLRoleBatchSetRequest - } - var newReq NewACLRoleBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - for _, role := range newReq.Roles { - if !IsEnterpriseData(role.Namespace, role.Partition) { - newReq.ACLRoleBatchSetRequest.Roles = append(newReq.ACLRoleBatchSetRequest.Roles, role.ACLRole) - } - } - - *req = *newReq.ACLRoleBatchSetRequest - return nil -} - -func decodeACLBindingRuleBatchSet(buf []byte, req *structs.ACLBindingRuleBatchSetRequest) error { - type aCLBindingRule struct { - Namespace string - Partition string - *structs.ACLBindingRule - } - type NewACLBindingRuleBatchSetRequest struct { - BindingRules []*aCLBindingRule - *structs.ACLBindingRuleBatchSetRequest - } - var newReq NewACLBindingRuleBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - if newReq.ACLBindingRuleBatchSetRequest == nil { - newReq.ACLBindingRuleBatchSetRequest = &structs.ACLBindingRuleBatchSetRequest{} - } - for _, rule := range newReq.BindingRules { - if !IsEnterpriseData(rule.Namespace, rule.Partition) { - newReq.ACLBindingRuleBatchSetRequest.BindingRules = append(newReq.ACLBindingRuleBatchSetRequest.BindingRules, rule.ACLBindingRule) - } - } - - *req = *newReq.ACLBindingRuleBatchSetRequest - return nil -} - -func decodeACLAuthMethodBatchSet(buf []byte, req *structs.ACLAuthMethodBatchSetRequest) error { - type aCLAuthMethod struct { - Namespace string - Partition string - *structs.ACLAuthMethod - } - type NewACLAuthMethodBatchSetRequest struct { - AuthMethods []*aCLAuthMethod - *structs.ACLAuthMethodBatchSetRequest - } - var newReq NewACLAuthMethodBatchSetRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - if newReq.ACLAuthMethodBatchSetRequest == nil { - newReq.ACLAuthMethodBatchSetRequest = &structs.ACLAuthMethodBatchSetRequest{} - } - for _, authMethod := range newReq.AuthMethods { - if !IsEnterpriseData(authMethod.Namespace, authMethod.Partition) { - newReq.ACLAuthMethodBatchSetRequest.AuthMethods = append(newReq.ACLAuthMethodBatchSetRequest.AuthMethods, authMethod.ACLAuthMethod) - } - } - - *req = *newReq.ACLAuthMethodBatchSetRequest - return nil -} - -func decodeACLAuthMethodBatchDelete(buf []byte, req *structs.ACLAuthMethodBatchDeleteRequest) error { - type NewACLAuthMethodBatchDeleteRequest struct { - Namespace string - Partition string - *structs.ACLAuthMethodBatchDeleteRequest - } - - var newReq NewACLAuthMethodBatchDeleteRequest - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if IsEnterpriseData(newReq.Namespace, newReq.Partition) { - return ErrDroppingTenantedReq - } - - *req = *newReq.ACLAuthMethodBatchDeleteRequest - return nil -} - -func decodeServiceVirtualIP(buf []byte, req *state.ServiceVirtualIP) error { - type serviceName struct { - Namespace string - Partition string - *structs.ServiceName - } - type peeredServiceName struct { - ServiceName *serviceName - *structs.PeeredServiceName - } - type NewServiceVirtualIP struct { - Service *peeredServiceName - *state.ServiceVirtualIP - } - var newReq NewServiceVirtualIP - if err := structs.Decode(buf, &newReq); err != nil { - return err - } - - if newReq.Service != nil && newReq.Service.ServiceName != nil && IsEnterpriseData(newReq.Service.ServiceName.Namespace, newReq.Service.ServiceName.Partition) { - return ErrDroppingTenantedReq - } - newReq.ServiceVirtualIP.Service.ServiceName = *newReq.Service.ServiceName.ServiceName - *req = *newReq.ServiceVirtualIP - return nil -} - -func decodePeeringWrite(buf []byte, req *pbpeering.PeeringWriteRequest) error { - if err := structs.DecodeProto(buf, req); err != nil { - return err - } - - if req.Peering != nil && IsEnterpriseData("", req.Peering.Partition) { - return ErrDroppingTenantedReq - } - - return nil -} - -func decodePeeringDelete(buf []byte, req *pbpeering.PeeringDeleteRequest) error { - if err := structs.DecodeProto(buf, req); err != nil { - return err - } - - if IsEnterpriseData("", req.Partition) { - return ErrDroppingTenantedReq - } - - return nil -} - -func decodePeeringTrustBundleWrite(buf []byte, req *pbpeering.PeeringTrustBundleWriteRequest) error { - if err := structs.DecodeProto(buf, req); err != nil { - return err - } - - if IsEnterpriseData("", req.PeeringTrustBundle.Partition) { - return ErrDroppingTenantedReq - } - - return nil -} - -func decodePeeringTrustBundleDelete(buf []byte, req *pbpeering.PeeringTrustBundleDeleteRequest) error { - if err := structs.DecodeProto(buf, req); err != nil { - return err - } - - if IsEnterpriseData("", req.Partition) { - return ErrDroppingTenantedReq - } - - return nil -} - -func decodeConfigEntryOperation(buf []byte, req *structs.ConfigEntryRequest) error { - - newReq := &ShadowConfigEntryRequest{ - ConfigEntryRequest: req, - } - if err := structs.Decode(buf, newReq); err != nil { - return err - } - shadowConfigEntry := newReq.ConfigEntryRequest.Entry.(ShadowConfigentry) - if err := shadowConfigEntry.CheckEnt(); err != nil { - return err - } - req.Entry = shadowConfigEntry.GetRealConfigEntry() - return nil -} - -type ShadowConfigEntryRequest struct { - *structs.ConfigEntryRequest -} - -func (c *ShadowConfigEntryRequest) UnmarshalBinary(data []byte) error { - // First decode the kind prefix - var kind string - dec := codec.NewDecoderBytes(data, structs.MsgpackHandle) - if err := dec.Decode(&kind); err != nil { - return err - } - - // Then decode the real thing with appropriate kind of ConfigEntry - entry, err := MakeShadowConfigEntry(kind, "") - if err != nil { - return err - } - c.Entry = entry - // Alias juggling to prevent infinite recursive calls back to this decode - // method. - type Alias structs.ConfigEntryRequest - as := struct { - *Alias - }{ - Alias: (*Alias)(c.ConfigEntryRequest), - } - if err := dec.Decode(&as); err != nil { - return err - } - return nil -} -func MakeShadowConfigEntry(kind, name string) (structs.ConfigEntry, error) { - switch kind { - case structs.RateLimitIPConfig: - return nil, ErrDroppingTenantedReq - case structs.ServiceDefaults: - return &ShadowServiceConfigEntry{ServiceConfigEntry: &structs.ServiceConfigEntry{Name: name}}, nil - case structs.ProxyDefaults: - return &ShadowProxyConfigEntry{ProxyConfigEntry: &structs.ProxyConfigEntry{Name: name}}, nil - case structs.ServiceRouter: - return &ShadowServiceRouterConfigEntry{ServiceRouterConfigEntry: &structs.ServiceRouterConfigEntry{Name: name}}, nil - case structs.ServiceSplitter: - return &ShadowServiceSplitterConfigEntry{ServiceSplitterConfigEntry: &structs.ServiceSplitterConfigEntry{Name: name}}, nil - case structs.ServiceResolver: - return &ShadowServiceResolverConfigEntry{ServiceResolverConfigEntry: &structs.ServiceResolverConfigEntry{Name: name}}, nil - case structs.IngressGateway: - return &ShadowIngressGatewayConfigEntry{IngressGatewayConfigEntry: &structs.IngressGatewayConfigEntry{Name: name}}, nil - case structs.TerminatingGateway: - return &ShadowTerminatingGatewayConfigEntry{TerminatingGatewayConfigEntry: &structs.TerminatingGatewayConfigEntry{Name: name}}, nil - case structs.ServiceIntentions: - return &ShadowServiceIntentionsConfigEntry{ServiceIntentionsConfigEntry: &structs.ServiceIntentionsConfigEntry{Name: name}}, nil - case structs.MeshConfig: - return &ShadowMeshConfigEntry{MeshConfigEntry: &structs.MeshConfigEntry{}}, nil - case structs.ExportedServices: - return &ShadowExportedServicesConfigEntry{ExportedServicesConfigEntry: &structs.ExportedServicesConfigEntry{Name: name}}, nil - case structs.SamenessGroup: - return &ShadowSamenessGroupConfigEntry{SamenessGroupConfigEntry: &structs.SamenessGroupConfigEntry{Name: name}}, nil - case structs.APIGateway: - return &ShadowAPIGatewayConfigEntry{APIGatewayConfigEntry: &structs.APIGatewayConfigEntry{Name: name}}, nil - case structs.BoundAPIGateway: - return &ShadowBoundAPIGatewayConfigEntry{BoundAPIGatewayConfigEntry: &structs.BoundAPIGatewayConfigEntry{Name: name}}, nil - case structs.InlineCertificate: - return &ShadowInlineCertificateConfigEntry{InlineCertificateConfigEntry: &structs.InlineCertificateConfigEntry{Name: name}}, nil - case structs.HTTPRoute: - return &ShadowHTTPRouteConfigEntry{HTTPRouteConfigEntry: &structs.HTTPRouteConfigEntry{Name: name}}, nil - case structs.TCPRoute: - return &ShadowTCPRouteConfigEntry{TCPRouteConfigEntry: &structs.TCPRouteConfigEntry{Name: name}}, nil - case structs.JWTProvider: - return &ShadowJWTProviderConfigEntry{JWTProviderConfigEntry: &structs.JWTProviderConfigEntry{Name: name}}, nil - default: - return nil, fmt.Errorf("invalid config entry kind: %s", kind) - } -} - -type ShadowBase struct { - Namespace string - Partition string -} - -func (s ShadowBase) CheckEnt() error { - if IsEnterpriseData(s.Namespace, s.Partition) { - return ErrDroppingTenantedReq - } - return nil -} - -type ShadowConfigentry interface { - CheckEnt() error - GetRealConfigEntry() structs.ConfigEntry -} - -type ShadowProxyConfigEntry struct { - ShadowBase - *structs.ProxyConfigEntry -} - -func (s ShadowProxyConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.ProxyConfigEntry -} - -type ShadowServiceResolverConfigEntry struct { - ShadowBase - *structs.ServiceResolverConfigEntry -} - -func (s ShadowServiceResolverConfigEntry) CheckEnt() error { - if err := s.ShadowBase.CheckEnt(); err != nil { - return err - } - if s.ServiceResolverConfigEntry.Redirect != nil && (IsEnterpriseData(s.ServiceResolverConfigEntry.Redirect.Namespace, s.ServiceResolverConfigEntry.Redirect.Partition) || s.ServiceResolverConfigEntry.Redirect.SamenessGroup != "") { - return errIncompatibleTenantedData - } - for _, failover := range s.ServiceResolverConfigEntry.Failover { - if IsEnterpriseData(failover.Namespace, "") || failover.SamenessGroup != "" { - return errIncompatibleTenantedData - } - for _, target := range failover.Targets { - if IsEnterpriseData(target.Namespace, target.Partition) { - return errIncompatibleTenantedData - } - } - } - return nil -} - -func (s ShadowServiceResolverConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.ServiceResolverConfigEntry -} - -func (e *ShadowProxyConfigEntry) UnmarshalBinary(data []byte) error { - // The goal here is to add a post-decoding operation to - // decoding of a ProxyConfigEntry. The cleanest way I could - // find to do so was to implement the BinaryMarshaller interface - // and use a type alias to do the original round of decoding, - // followed by a MapWalk of the Config to coerce everything - // into JSON compatible types. - type Alias structs.ProxyConfigEntry - as := struct { - *ShadowBase - *Alias - }{ - ShadowBase: &e.ShadowBase, - Alias: (*Alias)(e.ProxyConfigEntry), - } - dec := codec.NewDecoderBytes(data, structs.MsgpackHandle) - if err := dec.Decode(&as); err != nil { - return err - } - config, err := lib.MapWalk(e.Config) - if err != nil { - return err - } - e.Config = config - return nil -} - -type ShadowUpstreamConfig struct { - ShadowBase - *structs.UpstreamConfig -} -type ShadowUpstreamConfiguration struct { - Overrides []*ShadowUpstreamConfig - *structs.UpstreamConfiguration -} -type ShadowServiceConfigEntry struct { - ShadowBase - UpstreamConfig *ShadowUpstreamConfiguration - *structs.ServiceConfigEntry -} - -func (s ShadowServiceConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - if s.UpstreamConfig != nil { - for _, override := range s.UpstreamConfig.Overrides { - if !IsEnterpriseData(override.Namespace, override.Partition) { - if s.ServiceConfigEntry.UpstreamConfig == nil { - s.ServiceConfigEntry.UpstreamConfig = &structs.UpstreamConfiguration{} - } - s.ServiceConfigEntry.UpstreamConfig.Overrides = append(s.ServiceConfigEntry.UpstreamConfig.Overrides, override.UpstreamConfig) - } - } - } - return s.ServiceConfigEntry -} - -type ShadowServiceRouterConfigEntry struct { - ShadowBase - *structs.ServiceRouterConfigEntry -} - -func (s ShadowServiceRouterConfigEntry) CheckEnt() error { - if err := s.ShadowBase.CheckEnt(); err != nil { - return err - } - for _, route := range s.ServiceRouterConfigEntry.Routes { - if IsEnterpriseData(route.Destination.Namespace, route.Destination.Partition) { - return errIncompatibleTenantedData - } - } - return nil -} - -func (s ShadowServiceRouterConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.ServiceRouterConfigEntry -} - -type ShadowServiceSplitterConfigEntry struct { - ShadowBase - *structs.ServiceSplitterConfigEntry -} - -func (s ShadowServiceSplitterConfigEntry) CheckEnt() error { - if err := s.ShadowBase.CheckEnt(); err != nil { - return err - } - for _, split := range s.ServiceSplitterConfigEntry.Splits { - if IsEnterpriseData(split.Namespace, split.Partition) { - return errIncompatibleTenantedData - } - } - return nil -} -func (s ShadowServiceSplitterConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.ServiceSplitterConfigEntry -} - -type ShadowIngressService struct { - ShadowBase - *structs.IngressService -} -type ShadowIngressListener struct { - Services []ShadowIngressService - *structs.IngressListener -} -type ShadowIngressGatewayConfigEntry struct { - ShadowBase - Listeners []ShadowIngressListener - *structs.IngressGatewayConfigEntry -} - -func (s ShadowIngressGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, listner := range s.Listeners { - for _, svc := range listner.Services { - if !IsEnterpriseData(svc.Namespace, svc.Partition) { - listner.IngressListener.Services = append(listner.IngressListener.Services, *svc.IngressService) - } - } - if len(listner.IngressListener.Services) == 0 { - continue - } - s.IngressGatewayConfigEntry.Listeners = append(s.IngressGatewayConfigEntry.Listeners, *listner.IngressListener) - } - return s.IngressGatewayConfigEntry -} - -type ShadowLinkedService struct { - ShadowBase - *structs.LinkedService -} - -type ShadowTerminatingGatewayConfigEntry struct { - ShadowBase - Services []ShadowLinkedService - *structs.TerminatingGatewayConfigEntry -} - -func (s ShadowTerminatingGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, svc := range s.Services { - if !IsEnterpriseData(svc.Namespace, svc.Partition) { - s.TerminatingGatewayConfigEntry.Services = append(s.TerminatingGatewayConfigEntry.Services, *svc.LinkedService) - } - } - return s.TerminatingGatewayConfigEntry -} - -type ShadowSourceIntention struct { - ShadowBase - *structs.SourceIntention -} -type ShadowServiceIntentionsConfigEntry struct { - ShadowBase - Sources []*ShadowSourceIntention - *structs.ServiceIntentionsConfigEntry -} - -func (s ShadowServiceIntentionsConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, source := range s.Sources { - if !IsEnterpriseData(source.Namespace, source.Partition) && source.SamenessGroup == "" { - s.ServiceIntentionsConfigEntry.Sources = append(s.ServiceIntentionsConfigEntry.Sources, source.SourceIntention) - } - } - return s.ServiceIntentionsConfigEntry -} - -type ShadowMeshConfigEntry struct { - ShadowBase - *structs.MeshConfigEntry -} - -func (s ShadowMeshConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.MeshConfigEntry -} - -type ShadowExportedServicesConfigEntry struct { - ShadowBase - *structs.ExportedServicesConfigEntry -} - -func (s ShadowExportedServicesConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - services := []structs.ExportedService{} - for _, svc := range s.ExportedServicesConfigEntry.Services { - if !IsEnterpriseData(svc.Namespace, "") { - consumers := []structs.ServiceConsumer{} - for _, consumer := range svc.Consumers { - if !IsEnterpriseData("", consumer.Partition) && consumer.SamenessGroup == "" { - consumers = append(consumers, consumer) - } - } - if len(consumers) == 0 { - continue - } - services = append(services, svc) - } - } - s.ExportedServicesConfigEntry.Services = services - return s.ExportedServicesConfigEntry -} - -type ShadowSamenessGroupConfigEntry struct { - ShadowBase - *structs.SamenessGroupConfigEntry -} - -func (s ShadowSamenessGroupConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.SamenessGroupConfigEntry -} - -type ShadowAPIGatewayConfigEntry struct { - ShadowBase - *structs.APIGatewayConfigEntry -} - -func (s ShadowAPIGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.APIGatewayConfigEntry -} - -type ShadowBoundAPIGatewayListener struct { - Routes []ShadowResourceReference - Certificates []ShadowResourceReference - *structs.BoundAPIGatewayListener -} -type ShadowBoundAPIGatewayConfigEntry struct { - ShadowBase - Listeners []ShadowBoundAPIGatewayListener - *structs.BoundAPIGatewayConfigEntry -} - -func (s ShadowBoundAPIGatewayConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, listner := range s.Listeners { - for _, route := range listner.Routes { - if !IsEnterpriseData(route.Namespace, route.Partition) { - listner.BoundAPIGatewayListener.Routes = append(listner.BoundAPIGatewayListener.Routes, *route.ResourceReference) - } - } - for _, cf := range listner.Certificates { - if !IsEnterpriseData(cf.Namespace, cf.Partition) { - listner.BoundAPIGatewayListener.Certificates = append(listner.BoundAPIGatewayListener.Certificates, *cf.ResourceReference) - } - } - s.BoundAPIGatewayConfigEntry.Listeners = append(s.BoundAPIGatewayConfigEntry.Listeners, *listner.BoundAPIGatewayListener) - } - return s.BoundAPIGatewayConfigEntry -} - -type ShadowInlineCertificateConfigEntry struct { - ShadowBase - *structs.InlineCertificateConfigEntry -} - -func (s ShadowInlineCertificateConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.InlineCertificateConfigEntry -} - -type ShadowHTTPService struct { - ShadowBase - *structs.HTTPService -} -type ShadowHTTPRouteRule struct { - Services []ShadowHTTPService - *structs.HTTPRouteRule -} -type ShadowResourceReference struct { - ShadowBase - *structs.ResourceReference -} -type ShadowHTTPRouteConfigEntry struct { - ShadowBase - Parents []ShadowResourceReference - Rules []ShadowHTTPRouteRule - *structs.HTTPRouteConfigEntry -} - -func (s ShadowHTTPRouteConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, parent := range s.Parents { - if !IsEnterpriseData(parent.Namespace, parent.Partition) { - s.HTTPRouteConfigEntry.Parents = append(s.HTTPRouteConfigEntry.Parents, *parent.ResourceReference) - } - } - for _, rule := range s.Rules { - for _, svc := range rule.Services { - if !IsEnterpriseData(svc.Namespace, svc.Partition) { - rule.HTTPRouteRule.Services = append(rule.HTTPRouteRule.Services, *svc.HTTPService) - } - } - s.HTTPRouteConfigEntry.Rules = append(s.HTTPRouteConfigEntry.Rules, *rule.HTTPRouteRule) - } - return s.HTTPRouteConfigEntry -} - -type ShadowTCPService struct { - ShadowBase - *structs.TCPService -} -type ShadowTCPRouteConfigEntry struct { - ShadowBase - Parents []ShadowResourceReference - Services []ShadowTCPService - *structs.TCPRouteConfigEntry -} - -func (s ShadowTCPRouteConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - for _, parent := range s.Parents { - if !IsEnterpriseData(parent.Namespace, parent.Partition) { - s.TCPRouteConfigEntry.Parents = append(s.TCPRouteConfigEntry.Parents, *parent.ResourceReference) - } - } - for _, svc := range s.Services { - if !IsEnterpriseData(svc.Namespace, svc.Partition) { - s.TCPRouteConfigEntry.Services = append(s.TCPRouteConfigEntry.Services, *svc.TCPService) - } - } - return s.TCPRouteConfigEntry -} - -type ShadowJWTProviderConfigEntry struct { - ShadowBase - *structs.JWTProviderConfigEntry -} - -func (s ShadowJWTProviderConfigEntry) GetRealConfigEntry() structs.ConfigEntry { - return s.JWTProviderConfigEntry -} diff --git a/agent/consul/fsm/fsm.go b/agent/consul/fsm/fsm.go index 5a350e4dae778..92a3931b5b331 100644 --- a/agent/consul/fsm/fsm.go +++ b/agent/consul/fsm/fsm.go @@ -195,10 +195,6 @@ func (c *FSM) Apply(log *raft.Log) interface{} { c.logger.Warn("ignoring unknown message type, upgrade to newer version", "type", msgType) return nil } - if structs.CEDowngrade && msgType >= 64 { - c.logger.Warn("ignoring enterprise message, for downgrading to oss", "type", msgType) - return nil - } panic(fmt.Errorf("failed to apply request: %#v", buf)) } @@ -267,10 +263,7 @@ func (c *FSM) Restore(old io.ReadCloser) error { return err } default: - if structs.CEDowngrade && msg >= 64 { - c.logger.Warn("ignoring enterprise message , for downgrading to oss", "type", msg) - return nil - } else if msg >= 64 { + if msg >= 64 { return fmt.Errorf("msg type <%d> is a Consul Enterprise log entry. Consul CE cannot restore it", msg) } else { return fmt.Errorf("Unrecognized msg type %d", msg) diff --git a/agent/consul/options.go b/agent/consul/options.go index 88c16bd1a99c5..6dc754b3aef70 100644 --- a/agent/consul/options.go +++ b/agent/consul/options.go @@ -49,7 +49,7 @@ type Deps struct { EnterpriseDeps } -// UseV2Resources returns true if "resource-apis" is present in the Experiments +// useV2Resources returns true if "resource-apis" is present in the Experiments // array of the agent config. func (d Deps) UseV2Resources() bool { if stringslice.Contains(d.Experiments, CatalogResourceExperimentName) { @@ -58,15 +58,6 @@ func (d Deps) UseV2Resources() bool { return false } -// UseV2Tenancy returns true if "v2tenancy" is present in the Experiments -// array of the agent config. -func (d Deps) UseV2Tenancy() bool { - if stringslice.Contains(d.Experiments, V2TenancyExperimentName) { - return true - } - return false -} - type GRPCClientConner interface { ClientConn(datacenter string) (*grpc.ClientConn, error) ClientConnLeader() (*grpc.ClientConn, error) diff --git a/agent/consul/server.go b/agent/consul/server.go index 7986725b80169..9540cbe1c0fde 100644 --- a/agent/consul/server.go +++ b/agent/consul/server.go @@ -79,7 +79,6 @@ import ( "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/internal/resource/reaper" raftstorage "github.com/hashicorp/consul/internal/storage/raft" - "github.com/hashicorp/consul/internal/tenancy" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/routine" "github.com/hashicorp/consul/lib/stringslice" @@ -468,9 +467,6 @@ type Server struct { registry resource.Registry useV2Resources bool - - // useV2Tenancy is tied to the "v2tenancy" feature flag. - useV2Tenancy bool } func (s *Server) DecrementBlockingQueries() uint64 { @@ -560,7 +556,6 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, routineManager: routine.NewManager(logger.Named(logging.ConsulServer)), registry: flat.Registry, useV2Resources: flat.UseV2Resources(), - useV2Tenancy: flat.UseV2Tenancy(), } incomingRPCLimiter.Register(s) @@ -838,7 +833,7 @@ func NewServer(config *Config, flat Deps, externalGRPCServer *grpc.Server, go s.reportingManager.Run(&lib.StopChannelContext{StopCh: s.shutdownCh}) // Setup insecure resource service client. - if err := s.setupInsecureResourceServiceClient(flat.Registry, logger); err != nil { + if err := s.setupInsecureResourceServiceClient(flat.Registry, logger, flat); err != nil { return nil, err } @@ -935,14 +930,6 @@ func isV1CatalogRequest(rpcName string) bool { } func (s *Server) registerControllers(deps Deps, proxyUpdater ProxyUpdater) error { - // When not enabled, the v1 tenancy bridge is used by default. - if s.useV2Tenancy { - tenancy.RegisterControllers( - s.controllerManager, - tenancy.Dependencies{Registry: deps.Registry}, - ) - } - if s.useV2Resources { catalog.RegisterControllers(s.controllerManager, catalog.DefaultControllerDependencies()) @@ -989,7 +976,7 @@ func (s *Server) registerControllers(deps Deps, proxyUpdater ProxyUpdater) error demo.RegisterControllers(s.controllerManager) } - return s.controllerManager.ValidateDependencies(s.registry.Types()) + return nil } func newGRPCHandlerFromConfig(deps Deps, config *Config, s *Server) connHandler { @@ -1468,9 +1455,8 @@ func (s *Server) setupExternalGRPC(config *Config, deps Deps, logger hclog.Logge s.peerStreamServer.Register(s.externalGRPCServer) tenancyBridge := NewV1TenancyBridge(s) - if s.useV2Tenancy { - tenancyBridgeV2 := tenancy.NewV2TenancyBridge() - tenancyBridge = tenancyBridgeV2.WithClient(s.insecureResourceServiceClient) + if stringslice.Contains(deps.Experiments, V2TenancyExperimentName) { + tenancyBridge = resource.NewV2TenancyBridge() } s.resourceServiceServer = resourcegrpc.NewServer(resourcegrpc.Config{ @@ -1479,23 +1465,20 @@ func (s *Server) setupExternalGRPC(config *Config, deps Deps, logger hclog.Logge ACLResolver: s.ACLResolver, Logger: logger.Named("grpc-api.resource"), TenancyBridge: tenancyBridge, - UseV2Tenancy: s.useV2Tenancy, }) s.resourceServiceServer.Register(s.externalGRPCServer) reflection.Register(s.externalGRPCServer) } -func (s *Server) setupInsecureResourceServiceClient(typeRegistry resource.Registry, logger hclog.Logger) error { +func (s *Server) setupInsecureResourceServiceClient(typeRegistry resource.Registry, logger hclog.Logger, deps Deps) error { if s.raftStorageBackend == nil { return fmt.Errorf("raft storage backend cannot be nil") } - // Can't use interface type var here since v2 specific "WithClient(...)" is called futher down. tenancyBridge := NewV1TenancyBridge(s) - tenancyBridgeV2 := tenancy.NewV2TenancyBridge() - if s.useV2Tenancy { - tenancyBridge = tenancyBridgeV2 + if stringslice.Contains(deps.Experiments, V2TenancyExperimentName) { + tenancyBridge = resource.NewV2TenancyBridge() } server := resourcegrpc.NewServer(resourcegrpc.Config{ Registry: typeRegistry, @@ -1503,7 +1486,6 @@ func (s *Server) setupInsecureResourceServiceClient(typeRegistry resource.Regist ACLResolver: resolver.DANGER_NO_AUTH{}, Logger: logger.Named("grpc-api.resource"), TenancyBridge: tenancyBridge, - UseV2Tenancy: s.useV2Tenancy, }) conn, err := s.runInProcessGRPCServer(server.Register) @@ -1511,7 +1493,7 @@ func (s *Server) setupInsecureResourceServiceClient(typeRegistry resource.Regist return err } s.insecureResourceServiceClient = pbresource.NewResourceServiceClient(conn) - tenancyBridgeV2.WithClient(s.insecureResourceServiceClient) + return nil } diff --git a/agent/consul/server_test.go b/agent/consul/server_test.go index 95fa102d4a464..0ae028cbf2f2b 100644 --- a/agent/consul/server_test.go +++ b/agent/consul/server_test.go @@ -6,11 +6,9 @@ package consul import ( "context" "crypto/x509" - "flag" "fmt" "net" "os" - "path/filepath" "reflect" "strings" "sync" @@ -38,12 +36,10 @@ import ( external "github.com/hashicorp/consul/agent/grpc-external" grpcmiddleware "github.com/hashicorp/consul/agent/grpc-middleware" hcpclient "github.com/hashicorp/consul/agent/hcp/client" - "github.com/hashicorp/consul/agent/leafcert" "github.com/hashicorp/consul/agent/metadata" "github.com/hashicorp/consul/agent/rpc/middleware" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/agent/token" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" "github.com/hashicorp/consul/ipaddr" "github.com/hashicorp/consul/sdk/freeport" "github.com/hashicorp/consul/sdk/testutil" @@ -341,8 +337,7 @@ func newServerWithDeps(t *testing.T, c *Config, deps Deps) (*Server, error) { } } grpcServer := external.NewServer(deps.Logger.Named("grpc.external"), nil, deps.TLSConfigurator, rpcRate.NullRequestLimitsHandler(), keepalive.ServerParameters{}) - proxyUpdater := proxytracker.NewProxyTracker(proxytracker.ProxyTrackerConfig{}) - srv, err := NewServer(c, deps, grpcServer, nil, deps.Logger, proxyUpdater) + srv, err := NewServer(c, deps, grpcServer, nil, deps.Logger, nil) if err != nil { return nil, err } @@ -2106,38 +2101,3 @@ func TestServer_hcpManager(t *testing.T) { hcp1.AssertExpectations(t) } - -// goldenMarkdown reads and optionally writes the expected data to the goldenMarkdown file, -// returning the contents as a string. -func goldenMarkdown(t *testing.T, name, got string) string { - t.Helper() - - golden := filepath.Join("testdata", name+".md") - update := flag.Lookup("update").Value.(flag.Getter).Get().(bool) - if update && got != "" { - err := os.WriteFile(golden, []byte(got), 0644) - require.NoError(t, err) - } - - expected, err := os.ReadFile(golden) - require.NoError(t, err) - - return string(expected) -} - -func TestServer_ControllerDependencies(t *testing.T) { - t.Parallel() - - _, conf := testServerConfig(t) - deps := newDefaultDeps(t, conf) - deps.Experiments = []string{"resource-apis"} - deps.LeafCertManager = &leafcert.Manager{} - - s1, err := newServerWithDeps(t, conf, deps) - require.NoError(t, err) - - waitForLeaderEstablishment(t, s1) - actual := fmt.Sprintf("```mermaid\n%s\n```", s1.controllerManager.CalculateDependencies(s1.registry.Types()).ToMermaid()) - expected := goldenMarkdown(t, "v2-resource-dependencies", actual) - require.Equal(t, expected, actual) -} diff --git a/agent/consul/state/peering.go b/agent/consul/state/peering.go index 05dfa59a37af3..1763777cff838 100644 --- a/agent/consul/state/peering.go +++ b/agent/consul/state/peering.go @@ -202,9 +202,6 @@ func (s *Store) peeringSecretsWriteTxn(tx WriteTxn, req *pbpeering.SecretsWriteR return fmt.Errorf("failed to read peering by id: %w", err) } if peering == nil { - if structs.CEDowngrade { - return nil - } return fmt.Errorf("unknown peering %q for secret", req.PeerID) } diff --git a/agent/consul/testdata/v2-resource-dependencies.md b/agent/consul/testdata/v2-resource-dependencies.md deleted file mode 100644 index 1e34812446a41..0000000000000 --- a/agent/consul/testdata/v2-resource-dependencies.md +++ /dev/null @@ -1,45 +0,0 @@ -```mermaid -flowchart TD - auth/v2beta1/computedtrafficpermissions --> auth/v2beta1/trafficpermissions - auth/v2beta1/computedtrafficpermissions --> auth/v2beta1/workloadidentity - catalog/v2beta1/failoverpolicy --> catalog/v2beta1/service - catalog/v2beta1/healthstatus - catalog/v2beta1/node --> catalog/v2beta1/healthstatus - catalog/v2beta1/service - catalog/v2beta1/serviceendpoints --> catalog/v2beta1/service - catalog/v2beta1/serviceendpoints --> catalog/v2beta1/workload - catalog/v2beta1/workload --> catalog/v2beta1/healthstatus - catalog/v2beta1/workload --> catalog/v2beta1/node - demo/v1/album - demo/v1/artist - demo/v1/concept - demo/v1/executive - demo/v1/recordlabel - demo/v2/album - demo/v2/artist - internal/v1/tombstone - mesh/v2beta1/computedexplicitdestinations --> catalog/v2beta1/service - mesh/v2beta1/computedexplicitdestinations --> catalog/v2beta1/workload - mesh/v2beta1/computedexplicitdestinations --> mesh/v2beta1/computedroutes - mesh/v2beta1/computedexplicitdestinations --> mesh/v2beta1/destinations - mesh/v2beta1/computedproxyconfiguration --> catalog/v2beta1/workload - mesh/v2beta1/computedproxyconfiguration --> mesh/v2beta1/proxyconfiguration - mesh/v2beta1/computedroutes --> catalog/v2beta1/failoverpolicy - mesh/v2beta1/computedroutes --> catalog/v2beta1/service - mesh/v2beta1/computedroutes --> mesh/v2beta1/destinationpolicy - mesh/v2beta1/computedroutes --> mesh/v2beta1/grpcroute - mesh/v2beta1/computedroutes --> mesh/v2beta1/httproute - mesh/v2beta1/computedroutes --> mesh/v2beta1/tcproute - mesh/v2beta1/destinationpolicy - mesh/v2beta1/destinations - mesh/v2beta1/grpcroute - mesh/v2beta1/httproute - mesh/v2beta1/proxyconfiguration - mesh/v2beta1/proxystatetemplate --> auth/v2beta1/computedtrafficpermissions - mesh/v2beta1/proxystatetemplate --> catalog/v2beta1/service - mesh/v2beta1/proxystatetemplate --> catalog/v2beta1/workload - mesh/v2beta1/proxystatetemplate --> mesh/v2beta1/computedexplicitdestinations - mesh/v2beta1/proxystatetemplate --> mesh/v2beta1/computedproxyconfiguration - mesh/v2beta1/proxystatetemplate --> mesh/v2beta1/computedroutes - mesh/v2beta1/tcproute -``` \ No newline at end of file diff --git a/agent/consul/type_registry.go b/agent/consul/type_registry.go index 8bf093c41a112..d93309159d4bb 100644 --- a/agent/consul/type_registry.go +++ b/agent/consul/type_registry.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/consul/internal/auth" "github.com/hashicorp/consul/internal/catalog" "github.com/hashicorp/consul/internal/mesh" - "github.com/hashicorp/consul/internal/multicluster" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/internal/tenancy" @@ -28,7 +27,6 @@ func NewTypeRegistry() resource.Registry { catalog.RegisterTypes(registry) auth.RegisterTypes(registry) tenancy.RegisterTypes(registry) - multicluster.RegisterTypes(registry) return registry } diff --git a/agent/grpc-external/services/resource/delete.go b/agent/grpc-external/services/resource/delete.go index aef2934141c8a..2f30e27f983fb 100644 --- a/agent/grpc-external/services/resource/delete.go +++ b/agent/grpc-external/services/resource/delete.go @@ -7,7 +7,6 @@ import ( "context" "errors" "fmt" - "strings" "time" "github.com/oklog/ulid/v2" @@ -28,7 +27,7 @@ import ( // - Errors with Aborted if the requested Version does not match the stored Version. // - Errors with PermissionDenied if ACL check fails func (s *Server) Delete(ctx context.Context, req *pbresource.DeleteRequest) (*pbresource.DeleteResponse, error) { - reg, err := s.ensureDeleteRequestValid(req) + reg, err := s.validateDeleteRequest(req) if err != nil { return nil, err } @@ -74,18 +73,6 @@ func (s *Server) Delete(ctx context.Context, req *pbresource.DeleteRequest) (*pb deleteId = existing.Id } - // Check finalizers for a deferred delete - if resource.HasFinalizers(existing) { - if resource.IsMarkedForDeletion(existing) { - // Delete previously requested and finalizers still present so nothing to do - return &pbresource.DeleteResponse{}, nil - } - - // Mark for deletion and let controllers that put finalizers in place do their thing - return s.markForDeletion(ctx, existing) - } - - // Continue with an immediate delete if err := s.maybeCreateTombstone(ctx, deleteId); err != nil { return nil, err } @@ -101,20 +88,6 @@ func (s *Server) Delete(ctx context.Context, req *pbresource.DeleteRequest) (*pb } } -func (s *Server) markForDeletion(ctx context.Context, res *pbresource.Resource) (*pbresource.DeleteResponse, error) { - if res.Metadata == nil { - res.Metadata = map[string]string{} - } - res.Metadata[resource.DeletionTimestampKey] = time.Now().Format(time.RFC3339) - - // Write the deletion timestamp - _, err := s.Write(ctx, &pbresource.WriteRequest{Resource: res}) - if err != nil { - return nil, err - } - return &pbresource.DeleteResponse{}, nil -} - // Create a tombstone to capture the intent to delete child resources. // Tombstones are created preemptively to prevent partial failures even though // we are currently unaware of the success/failure/no-op of DeleteCAS. In @@ -171,7 +144,7 @@ func (s *Server) maybeCreateTombstone(ctx context.Context, deleteId *pbresource. } } -func (s *Server) ensureDeleteRequestValid(req *pbresource.DeleteRequest) (*resource.Registration, error) { +func (s *Server) validateDeleteRequest(req *pbresource.DeleteRequest) (*resource.Registration, error) { if req.Id == nil { return nil, status.Errorf(codes.InvalidArgument, "id is required") } @@ -185,10 +158,6 @@ func (s *Server) ensureDeleteRequestValid(req *pbresource.DeleteRequest) (*resou return nil, err } - if err = checkV2Tenancy(s.UseV2Tenancy, req.Id.Type); err != nil { - return nil, err - } - // Check scope if reg.Scope == resource.ScopePartition && req.Id.Tenancy.Namespace != "" { return nil, status.Errorf( @@ -206,5 +175,5 @@ func (s *Server) ensureDeleteRequestValid(req *pbresource.DeleteRequest) (*resou // name by embedding the resources's Uid in the name. func tombstoneName(deleteId *pbresource.ID) string { // deleteId.Name is just included for easier identification - return fmt.Sprintf("tombstone-%v-%v", deleteId.Name, strings.ToLower(deleteId.Uid)) + return fmt.Sprintf("tombstone-%v-%v", deleteId.Name, deleteId.Uid) } diff --git a/agent/grpc-external/services/resource/delete_test.go b/agent/grpc-external/services/resource/delete_test.go index 4c13393138629..5f5d7d7e21920 100644 --- a/agent/grpc-external/services/resource/delete_test.go +++ b/agent/grpc-external/services/resource/delete_test.go @@ -5,7 +5,6 @@ package resource import ( "context" - "strings" "testing" "github.com/stretchr/testify/mock" @@ -17,106 +16,45 @@ import ( "github.com/hashicorp/consul/acl/resolver" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/demo" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" "github.com/hashicorp/consul/proto-public/pbresource" - pbdemo "github.com/hashicorp/consul/proto/private/pbdemo/v1" ) func TestDelete_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(artistId, recordLabelId *pbresource.ID) *pbresource.ID - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no id": { - modFn: func(_, _ *pbresource.ID) *pbresource.ID { - return nil - }, - errContains: "id is required", - }, - "no type": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Type = nil - return artistId - }, - errContains: "id.type is required", - }, - "no name": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "" - return artistId - }, - errContains: "id.name invalid", - }, - "mixed case name": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "DepecheMode" - return artistId - }, - errContains: "id.name invalid", - }, - "name too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.name invalid", - }, - "partition mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = "Default" - return artistId - }, - errContains: "id.tenancy.partition invalid", + testCases := map[string]func(artistId, recordLabelId *pbresource.ID) *pbresource.ID{ + "no id": func(artistId, recordLabelId *pbresource.ID) *pbresource.ID { + return nil }, - "partition name too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.tenancy.partition invalid", - }, - "namespace mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = "Default" - return artistId - }, - errContains: "id.tenancy.namespace invalid", + "no type": func(artistId, _ *pbresource.ID) *pbresource.ID { + artistId.Type = nil + return artistId }, - "namespace name too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.tenancy.namespace invalid", + "no name": func(artistId, _ *pbresource.ID) *pbresource.ID { + artistId.Name = "" + return artistId }, - "partition scoped resource with namespace": { - modFn: func(_, recordLabelId *pbresource.ID) *pbresource.ID { - recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" - return recordLabelId - }, - errContains: "cannot have a namespace", + "partition scoped resource with namespace": func(_, recordLabelId *pbresource.ID) *pbresource.ID { + recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" + return recordLabelId }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) artist, err := demo.GenerateV2Artist() require.NoError(t, err) - req := &pbresource.DeleteRequest{Id: tc.modFn(artist.Id, recordLabel.Id), Version: ""} + req := &pbresource.DeleteRequest{Id: modFn(artist.Id, recordLabel.Id), Version: ""} _, err = client.Delete(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -191,7 +129,7 @@ func TestDelete_Success(t *testing.T) { server, client, ctx := testDeps(t) demo.RegisterTypes(server.Registry) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) writeRsp, err := client.Write(ctx, &pbresource.WriteRequest{Resource: recordLabel}) require.NoError(t, err) @@ -315,68 +253,6 @@ func TestDelete_VersionMismatch(t *testing.T) { require.ErrorContains(t, err, "CAS operation failed") } -func TestDelete_MarkedForDeletionWhenFinalizersPresent(t *testing.T) { - server, client, ctx := testDeps(t) - demo.RegisterTypes(server.Registry) - - // Create a resource with a finalizer - res := rtest.Resource(demo.TypeV1Artist, "manwithnoname"). - WithTenancy(resource.DefaultClusteredTenancy()). - WithData(t, &pbdemo.Artist{Name: "Man With No Name"}). - WithMeta(resource.FinalizerKey, "finalizer1"). - Write(t, client) - - // Delete it - _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) - - // Verify resource has been marked for deletion - rsp, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - require.True(t, resource.IsMarkedForDeletion(rsp.Resource)) - - // Delete again - should be no-op - _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) - - // Verify no-op by checking version still the same - rsp2, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - rtest.RequireVersionUnchanged(t, rsp2.Resource, rsp.Resource.Version) -} - -func TestDelete_ImmediatelyDeletedAfterFinalizersRemoved(t *testing.T) { - server, client, ctx := testDeps(t) - demo.RegisterTypes(server.Registry) - - // Create a resource with a finalizer - res := rtest.Resource(demo.TypeV1Artist, "manwithnoname"). - WithTenancy(resource.DefaultClusteredTenancy()). - WithData(t, &pbdemo.Artist{Name: "Man With No Name"}). - WithMeta(resource.FinalizerKey, "finalizer1"). - Write(t, client) - - // Delete should mark it for deletion - _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) - - // Remove the finalizer - rsp, err := client.Read(ctx, &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - resource.RemoveFinalizer(rsp.Resource, "finalizer1") - _, err = client.Write(ctx, &pbresource.WriteRequest{Resource: rsp.Resource}) - require.NoError(t, err) - - // Delete should be immediate - _, err = client.Delete(ctx, &pbresource.DeleteRequest{Id: rsp.Resource.Id}) - require.NoError(t, err) - - // Verify deleted - _, err = client.Read(ctx, &pbresource.ReadRequest{Id: rsp.Resource.Id}) - require.Error(t, err) - require.Equal(t, codes.NotFound.String(), status.Code(err).String()) -} - func testDeps(t *testing.T) (*Server, pbresource.ResourceServiceClient, context.Context) { server := testServer(t) client := testClient(t, server) diff --git a/agent/grpc-external/services/resource/list.go b/agent/grpc-external/services/resource/list.go index dc7f88a404c8e..c1ecb253448ce 100644 --- a/agent/grpc-external/services/resource/list.go +++ b/agent/grpc-external/services/resource/list.go @@ -16,7 +16,7 @@ import ( ) func (s *Server) List(ctx context.Context, req *pbresource.ListRequest) (*pbresource.ListResponse, error) { - reg, err := s.ensureListRequestValid(req) + reg, err := s.validateListRequest(req) if err != nil { return nil, err } @@ -81,7 +81,7 @@ func (s *Server) List(ctx context.Context, req *pbresource.ListRequest) (*pbreso return &pbresource.ListResponse{Resources: result}, nil } -func (s *Server) ensureListRequestValid(req *pbresource.ListRequest) (*resource.Registration, error) { +func (s *Server) validateListRequest(req *pbresource.ListRequest) (*resource.Registration, error) { var field string switch { case req.Type == nil: @@ -100,13 +100,8 @@ func (s *Server) ensureListRequestValid(req *pbresource.ListRequest) (*resource. return nil, err } - if err = checkV2Tenancy(s.UseV2Tenancy, req.Type); err != nil { - return nil, err - } - - if err := validateWildcardTenancy(req.Tenancy, req.NamePrefix); err != nil { - return nil, err - } + // Lowercase + resource.Normalize(req.Tenancy) // Error when partition scoped and namespace not empty. if reg.Scope == resource.ScopePartition && req.Tenancy.Namespace != "" { diff --git a/agent/grpc-external/services/resource/list_by_owner.go b/agent/grpc-external/services/resource/list_by_owner.go index e810ce31a4d0f..2310a5b50eda2 100644 --- a/agent/grpc-external/services/resource/list_by_owner.go +++ b/agent/grpc-external/services/resource/list_by_owner.go @@ -15,7 +15,7 @@ import ( ) func (s *Server) ListByOwner(ctx context.Context, req *pbresource.ListByOwnerRequest) (*pbresource.ListByOwnerResponse, error) { - reg, err := s.ensureListByOwnerRequestValid(req) + reg, err := s.validateListByOwnerRequest(req) if err != nil { return nil, err } @@ -42,8 +42,8 @@ func (s *Server) ListByOwner(ctx context.Context, req *pbresource.ListByOwnerReq return nil, status.Errorf(codes.Internal, "failed list acl: %v", err) } - // Check tenancy exists for the v2 resource. - if err = tenancyExists(reg, s.TenancyBridge, req.Owner.Tenancy, codes.InvalidArgument); err != nil { + // Check v1 tenancy exists for the v2 resource. + if err = v1TenancyExists(reg, s.TenancyBridge, req.Owner.Tenancy, codes.InvalidArgument); err != nil { return nil, err } @@ -87,7 +87,7 @@ func (s *Server) ListByOwner(ctx context.Context, req *pbresource.ListByOwnerReq return &pbresource.ListByOwnerResponse{Resources: result}, nil } -func (s *Server) ensureListByOwnerRequestValid(req *pbresource.ListByOwnerRequest) (*resource.Registration, error) { +func (s *Server) validateListByOwnerRequest(req *pbresource.ListByOwnerRequest) (*resource.Registration, error) { if req.Owner == nil { return nil, status.Errorf(codes.InvalidArgument, "owner is required") } @@ -105,9 +105,8 @@ func (s *Server) ensureListByOwnerRequestValid(req *pbresource.ListByOwnerReques return nil, err } - if err = checkV2Tenancy(s.UseV2Tenancy, req.Owner.Type); err != nil { - return nil, err - } + // Lowercase + resource.Normalize(req.Owner.Tenancy) // Error when partition scoped and namespace not empty. if reg.Scope == resource.ScopePartition && req.Owner.Tenancy.Namespace != "" { diff --git a/agent/grpc-external/services/resource/list_by_owner_test.go b/agent/grpc-external/services/resource/list_by_owner_test.go index 78024e68d0fb2..11c6027c0b642 100644 --- a/agent/grpc-external/services/resource/list_by_owner_test.go +++ b/agent/grpc-external/services/resource/list_by_owner_test.go @@ -6,7 +6,6 @@ package resource import ( "context" "fmt" - "strings" "testing" "github.com/hashicorp/consul/acl" @@ -14,7 +13,6 @@ import ( "github.com/hashicorp/consul/internal/resource/demo" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/proto/private/prototest" - "github.com/oklog/ulid/v2" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -28,104 +26,41 @@ func TestListByOwner_InputValidation(t *testing.T) { client := testClient(t, server) demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(artistId, recordlabelId *pbresource.ID) *pbresource.ID - errContains string - } - testCases := map[string]testCase{ - "no owner": { - modFn: func(artistId, recordLabelId *pbresource.ID) *pbresource.ID { - return nil - }, - errContains: "owner is required", - }, - "no type": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Type = nil - return artistId - }, - errContains: "owner.type is required", - }, - "no name": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "" - return artistId - }, - errContains: "owner.name invalid", - }, - "name mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "U2" - return artistId - }, - errContains: "owner.name invalid", + testCases := map[string]func(artistId, recordlabelId *pbresource.ID) *pbresource.ID{ + "no owner": func(artistId, recordLabelId *pbresource.ID) *pbresource.ID { + return nil }, - "name too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "owner.name invalid", + "no type": func(artistId, _ *pbresource.ID) *pbresource.ID { + artistId.Type = nil + return artistId }, - "partition mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = "Default" - return artistId - }, - errContains: "owner.tenancy.partition invalid", + "no name": func(artistId, _ *pbresource.ID) *pbresource.ID { + artistId.Name = "" + return artistId }, - "partition too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - return artistId - }, - errContains: "owner.tenancy.partition invalid", + "no uid": func(artistId, _ *pbresource.ID) *pbresource.ID { + artistId.Uid = "" + return artistId }, - "namespace mixed case": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = "Default" - return artistId - }, - errContains: "owner.tenancy.namespace invalid", - }, - "namespace too long": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "owner.tenancy.namespace invalid", - }, - "no uid": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Uid = "" - return artistId - }, - errContains: "owner uid is required", - }, - "partition scope with non-empty namespace": { - modFn: func(_, recordLabelId *pbresource.ID) *pbresource.ID { - recordLabelId.Uid = ulid.Make().String() - recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" - return recordLabelId - }, - errContains: "cannot have a namespace", + "partition scope with non-empty namespace": func(_, recordLabelId *pbresource.ID) *pbresource.ID { + recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" + return recordLabelId }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { artist, err := demo.GenerateV2Artist() require.NoError(t, err) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) // Each test case picks which resource to use based on the resource type's scope. - req := &pbresource.ListByOwnerRequest{Owner: tc.modFn(artist.Id, recordLabel.Id)} + req := &pbresource.ListByOwnerRequest{Owner: modFn(artist.Id, recordLabel.Id)} _, err = client.ListByOwner(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -196,46 +131,33 @@ func TestListByOwner_Many(t *testing.T) { } func TestListByOwner_OwnerTenancyDoesNotExist(t *testing.T) { - type testCase struct { - modFn func(artistId, recordlabelId *pbresource.ID) *pbresource.ID - errContains string - } - tenancyCases := map[string]testCase{ - "partition not found when namespace scoped": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Uid = "doesnotmatter" - id.Tenancy.Partition = "boguspartition" - return id - }, - errContains: "partition not found", + tenancyCases := map[string]func(artistId, recordlabelId *pbresource.ID) *pbresource.ID{ + "partition not found when namespace scoped": func(artistId, _ *pbresource.ID) *pbresource.ID { + id := clone(artistId) + id.Uid = "doesnotmatter" + id.Tenancy.Partition = "boguspartition" + return id }, - "namespace not found when namespace scoped": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Uid = "doesnotmatter" - id.Tenancy.Namespace = "bogusnamespace" - return id - }, - errContains: "namespace not found", + "namespace not found when namespace scoped": func(artistId, _ *pbresource.ID) *pbresource.ID { + id := clone(artistId) + id.Uid = "doesnotmatter" + id.Tenancy.Namespace = "bogusnamespace" + return id }, - "partition not found when partition scoped": { - modFn: func(_, recordLabelId *pbresource.ID) *pbresource.ID { - id := clone(recordLabelId) - id.Uid = "doesnotmatter" - id.Tenancy.Partition = "boguspartition" - return id - }, - errContains: "partition not found", + "partition not found when partition scoped": func(_, recordLabelId *pbresource.ID) *pbresource.ID { + id := clone(recordLabelId) + id.Uid = "doesnotmatter" + id.Tenancy.Partition = "boguspartition" + return id }, } - for desc, tc := range tenancyCases { + for desc, modFn := range tenancyCases { t.Run(desc, func(t *testing.T) { server := testServer(t) demo.RegisterTypes(server.Registry) client := testClient(t, server) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) recordLabel, err = server.Backend.WriteCAS(testContext(t), recordLabel) require.NoError(t, err) @@ -245,11 +167,11 @@ func TestListByOwner_OwnerTenancyDoesNotExist(t *testing.T) { artist, err = server.Backend.WriteCAS(testContext(t), artist) require.NoError(t, err) - // Verify non-existant tenancy units in owner err with invalid arg. - _, err = client.ListByOwner(testContext(t), &pbresource.ListByOwnerRequest{Owner: tc.modFn(artist.Id, recordLabel.Id)}) + // Verify non-existant tenancy units in owner err with not found. + _, err = client.ListByOwner(testContext(t), &pbresource.ListByOwnerRequest{Owner: modFn(artist.Id, recordLabel.Id)}) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) + require.Contains(t, err.Error(), "resource not found") }) } } @@ -262,7 +184,7 @@ func TestListByOwner_Tenancy_Defaults_And_Normalization(t *testing.T) { client := testClient(t, server) // Create partition scoped recordLabel. - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) rsp1, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: recordLabel}) require.NoError(t, err) diff --git a/agent/grpc-external/services/resource/list_test.go b/agent/grpc-external/services/resource/list_test.go index 5af6747f84444..64026b7d34e59 100644 --- a/agent/grpc-external/services/resource/list_test.go +++ b/agent/grpc-external/services/resource/list_test.go @@ -6,8 +6,6 @@ package resource import ( "context" "fmt" - "strconv" - "strings" "testing" "github.com/hashicorp/consul/acl" @@ -28,66 +26,28 @@ import ( func TestList_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - demo.RegisterTypes(server.Registry) - type testCase struct { - modReqFn func(req *pbresource.ListRequest) - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no type": { - modReqFn: func(req *pbresource.ListRequest) { req.Type = nil }, - errContains: "type is required", - }, - "no tenancy": { - modReqFn: func(req *pbresource.ListRequest) { req.Tenancy = nil }, - errContains: "tenancy is required", - }, - "partition mixed case": { - modReqFn: func(req *pbresource.ListRequest) { req.Tenancy.Partition = "Default" }, - errContains: "tenancy.partition invalid", - }, - "partition too long": { - modReqFn: func(req *pbresource.ListRequest) { - req.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errContains: "tenancy.partition invalid", - }, - "namespace mixed case": { - modReqFn: func(req *pbresource.ListRequest) { req.Tenancy.Namespace = "Default" }, - errContains: "tenancy.namespace invalid", - }, - "namespace too long": { - modReqFn: func(req *pbresource.ListRequest) { - req.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errContains: "tenancy.namespace invalid", - }, - "name_prefix mixed case": { - modReqFn: func(req *pbresource.ListRequest) { req.NamePrefix = "Violator" }, - errContains: "name_prefix invalid", - }, - "partitioned resource provides non-empty namespace": { - modReqFn: func(req *pbresource.ListRequest) { - req.Type = demo.TypeV1RecordLabel - req.Tenancy.Namespace = "bad" - }, - errContains: "cannot have a namespace", + testCases := map[string]func(*pbresource.ListRequest){ + "no type": func(req *pbresource.ListRequest) { req.Type = nil }, + "no tenancy": func(req *pbresource.ListRequest) { req.Tenancy = nil }, + "partitioned resource provides non-empty namespace": func(req *pbresource.ListRequest) { + req.Type = demo.TypeV1RecordLabel + req.Tenancy.Namespace = "bad" }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { req := &pbresource.ListRequest{ Type: demo.TypeV2Album, Tenancy: resource.DefaultNamespacedTenancy(), } - tc.modReqFn(req) + modFn(req) _, err := client.List(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -156,46 +116,6 @@ func TestList_Many(t *testing.T) { } } -func TestList_NamePrefix(t *testing.T) { - for desc, tc := range listTestCases() { - t.Run(desc, func(t *testing.T) { - server := testServer(t) - demo.RegisterTypes(server.Registry) - client := testClient(t, server) - - expectedResources := []*pbresource.Resource{} - - namePrefixIndex := 0 - // create a name prefix that is always present - namePrefix := fmt.Sprintf("%s-", strconv.Itoa(namePrefixIndex)) - for i := 0; i < 10; i++ { - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - // Prevent test flakes if the generated names collide. - artist.Id.Name = fmt.Sprintf("%d-%s", i, artist.Id.Name) - - rsp, err := client.Write(tc.ctx, &pbresource.WriteRequest{Resource: artist}) - require.NoError(t, err) - - // only matching name prefix are expected - if i == namePrefixIndex { - expectedResources = append(expectedResources, rsp.Resource) - } - } - - rsp, err := client.List(tc.ctx, &pbresource.ListRequest{ - Type: demo.TypeV2Artist, - Tenancy: resource.DefaultNamespacedTenancy(), - NamePrefix: namePrefix, - }) - - require.NoError(t, err) - prototest.AssertElementsMatch(t, expectedResources, rsp.Resources) - }) - } -} - func TestList_Tenancy_Defaults_And_Normalization(t *testing.T) { // Test units of tenancy get defaulted correctly when empty. ctx := context.Background() @@ -206,7 +126,7 @@ func TestList_Tenancy_Defaults_And_Normalization(t *testing.T) { client := testClient(t, server) // Write partition scoped record label - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LooneyTunes") require.NoError(t, err) recordLabelRsp, err := client.Write(ctx, &pbresource.WriteRequest{Resource: recordLabel}) require.NoError(t, err) @@ -230,6 +150,7 @@ func TestList_Tenancy_Defaults_And_Normalization(t *testing.T) { prototest.AssertDeepEqual(t, artistRsp.Resource, listRsp.Resources[0]) } }) + } } diff --git a/agent/grpc-external/services/resource/read.go b/agent/grpc-external/services/resource/read.go index 9fe59024ce8e6..b6cec37254566 100644 --- a/agent/grpc-external/services/resource/read.go +++ b/agent/grpc-external/services/resource/read.go @@ -18,7 +18,7 @@ import ( func (s *Server) Read(ctx context.Context, req *pbresource.ReadRequest) (*pbresource.ReadResponse, error) { // Light first pass validation based on what user passed in and not much more. - reg, err := s.ensureReadRequestValid(req) + reg, err := s.validateReadRequest(req) if err != nil { return nil, err } @@ -59,8 +59,8 @@ func (s *Server) Read(ctx context.Context, req *pbresource.ReadRequest) (*pbreso return nil, status.Errorf(codes.Internal, "failed read acl: %v", err) } - // Check tenancy exists for the V2 resource. - if err = tenancyExists(reg, s.TenancyBridge, req.Id.Tenancy, codes.NotFound); err != nil { + // Check V1 tenancy exists for the V2 resource. + if err = v1TenancyExists(reg, s.TenancyBridge, req.Id.Tenancy, codes.NotFound); err != nil { return nil, err } @@ -87,7 +87,7 @@ func (s *Server) Read(ctx context.Context, req *pbresource.ReadRequest) (*pbreso return &pbresource.ReadResponse{Resource: resource}, nil } -func (s *Server) ensureReadRequestValid(req *pbresource.ReadRequest) (*resource.Registration, error) { +func (s *Server) validateReadRequest(req *pbresource.ReadRequest) (*resource.Registration, error) { if req.Id == nil { return nil, status.Errorf(codes.InvalidArgument, "id is required") } @@ -102,14 +102,32 @@ func (s *Server) ensureReadRequestValid(req *pbresource.ReadRequest) (*resource. return nil, err } - if err = checkV2Tenancy(s.UseV2Tenancy, req.Id.Type); err != nil { - return nil, err - } - // Check scope - if err = validateScopedTenancy(reg.Scope, req.Id.Type, req.Id.Tenancy); err != nil { - return nil, err + if reg.Scope == resource.ScopePartition && req.Id.Tenancy.Namespace != "" { + return nil, status.Errorf( + codes.InvalidArgument, + "partition scoped resource %s cannot have a namespace. got: %s", + resource.ToGVK(req.Id.Type), + req.Id.Tenancy.Namespace, + ) + } + if reg.Scope == resource.ScopeCluster { + if req.Id.Tenancy.Partition != "" { + return nil, status.Errorf( + codes.InvalidArgument, + "cluster scoped resource %s cannot have a partition: %s", + resource.ToGVK(req.Id.Type), + req.Id.Tenancy.Partition, + ) + } + if req.Id.Tenancy.Namespace != "" { + return nil, status.Errorf( + codes.InvalidArgument, + "cluster scoped resource %s cannot have a namespace: %s", + resource.ToGVK(req.Id.Type), + req.Id.Tenancy.Namespace, + ) + } } - return reg, nil } diff --git a/agent/grpc-external/services/resource/read_test.go b/agent/grpc-external/services/resource/read_test.go index 2afdfeab0e1ea..2601689bc6c4b 100644 --- a/agent/grpc-external/services/resource/read_test.go +++ b/agent/grpc-external/services/resource/read_test.go @@ -6,7 +6,6 @@ package resource import ( "context" "fmt" - "strings" "sync" "testing" @@ -35,114 +34,46 @@ func TestRead_InputValidation(t *testing.T) { tenancy.RegisterTypes(server.Registry) demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(artistId, recordlabelId, executiveId *pbresource.ID) *pbresource.ID - errContains string - } - - testCases := map[string]testCase{ - "no id": { - modFn: func(_, _, _ *pbresource.ID) *pbresource.ID { - return nil - }, - errContains: "id is required", - }, - "no type": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Type = nil - return artistId - }, - errContains: "id.type is required", - }, - "no name": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "" - return artistId - }, - errContains: "id.name invalid", - }, - "name is mixed case": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "MixedCaseNotAllowed" - return artistId - }, - errContains: "id.name invalid", + testCases := map[string]func(artistId, recordlabelId, executiveId *pbresource.ID) *pbresource.ID{ + "no id": func(_, _, _ *pbresource.ID) *pbresource.ID { return nil }, + "no type": func(artistId, _, _ *pbresource.ID) *pbresource.ID { + artistId.Type = nil + return artistId }, - "name too long": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Name = strings.Repeat("a", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.name invalid", + "no name": func(artistId, _, _ *pbresource.ID) *pbresource.ID { + artistId.Name = "" + return artistId }, - "partition is mixed case": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = "Default" - return artistId - }, - errContains: "id.tenancy.partition invalid", + "partition scope with non-empty namespace": func(_, recordLabelId, _ *pbresource.ID) *pbresource.ID { + recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" + return recordLabelId }, - "partition too long": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.tenancy.partition invalid", + "cluster scope with non-empty partition": func(_, _, executiveId *pbresource.ID) *pbresource.ID { + executiveId.Tenancy = &pbresource.Tenancy{Partition: resource.DefaultPartitionName} + return executiveId }, - "namespace is mixed case": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = "Default" - return artistId - }, - errContains: "id.tenancy.namespace invalid", - }, - "namespace too long": { - modFn: func(artistId, _, _ *pbresource.ID) *pbresource.ID { - artistId.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - return artistId - }, - errContains: "id.tenancy.namespace invalid", - }, - "partition scope with non-empty namespace": { - modFn: func(_, recordLabelId, _ *pbresource.ID) *pbresource.ID { - recordLabelId.Tenancy.Namespace = "ishouldnothaveanamespace" - return recordLabelId - }, - errContains: "cannot have a namespace", - }, - "cluster scope with non-empty partition": { - modFn: func(_, _, executiveId *pbresource.ID) *pbresource.ID { - executiveId.Tenancy = &pbresource.Tenancy{Partition: resource.DefaultPartitionName} - return executiveId - }, - errContains: "cannot have a partition", - }, - "cluster scope with non-empty namespace": { - modFn: func(_, _, executiveId *pbresource.ID) *pbresource.ID { - executiveId.Tenancy = &pbresource.Tenancy{Namespace: resource.DefaultNamespaceName} - return executiveId - }, - errContains: "cannot have a namespace", + "cluster scope with non-empty namespace": func(_, _, executiveId *pbresource.ID) *pbresource.ID { + executiveId.Tenancy = &pbresource.Tenancy{Namespace: resource.DefaultNamespaceName} + return executiveId }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { artist, err := demo.GenerateV2Artist() require.NoError(t, err) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) - executive, err := demo.GenerateV1Executive("music-man", "CEO") + executive, err := demo.GenerateV1Executive("MusicMan", "CEO") require.NoError(t, err) // Each test case picks which resource to use based on the resource type's scope. - req := &pbresource.ReadRequest{Id: tc.modFn(artist.Id, recordLabel.Id, executive.Id)} + req := &pbresource.ReadRequest{Id: modFn(artist.Id, recordLabel.Id, executive.Id)} _, err = client.Read(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -163,50 +94,34 @@ func TestRead_TypeNotFound(t *testing.T) { func TestRead_ResourceNotFound(t *testing.T) { for desc, tc := range readTestCases() { t.Run(desc, func(t *testing.T) { - type tenancyCase struct { - modFn func(artistId, recordlabelId *pbresource.ID) *pbresource.ID - errContains string - } - tenancyCases := map[string]tenancyCase{ - "resource not found by name": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - artistId.Name = "bogusname" - return artistId - }, - errContains: "resource not found", + tenancyCases := map[string]func(artistId, recordlabelId *pbresource.ID) *pbresource.ID{ + "resource not found by name": func(artistId, _ *pbresource.ID) *pbresource.ID { + artistId.Name = "bogusname" + return artistId }, - "partition not found when namespace scoped": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Tenancy.Partition = "boguspartition" - return id - }, - errContains: "partition not found", + "partition not found when namespace scoped": func(artistId, _ *pbresource.ID) *pbresource.ID { + id := clone(artistId) + id.Tenancy.Partition = "boguspartition" + return id }, - "namespace not found when namespace scoped": { - modFn: func(artistId, _ *pbresource.ID) *pbresource.ID { - id := clone(artistId) - id.Tenancy.Namespace = "bogusnamespace" - return id - }, - errContains: "namespace not found", + "namespace not found when namespace scoped": func(artistId, _ *pbresource.ID) *pbresource.ID { + id := clone(artistId) + id.Tenancy.Namespace = "bogusnamespace" + return id }, - "partition not found when partition scoped": { - modFn: func(_, recordLabelId *pbresource.ID) *pbresource.ID { - id := clone(recordLabelId) - id.Tenancy.Partition = "boguspartition" - return id - }, - errContains: "partition not found", + "partition not found when partition scoped": func(_, recordLabelId *pbresource.ID) *pbresource.ID { + id := clone(recordLabelId) + id.Tenancy.Partition = "boguspartition" + return id }, } - for tenancyDesc, tenancyCase := range tenancyCases { + for tenancyDesc, modFn := range tenancyCases { t.Run(tenancyDesc, func(t *testing.T) { server := testServer(t) demo.RegisterTypes(server.Registry) client := testClient(t, server) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) recordLabel, err = server.Backend.WriteCAS(tc.ctx, recordLabel) require.NoError(t, err) @@ -217,10 +132,10 @@ func TestRead_ResourceNotFound(t *testing.T) { require.NoError(t, err) // Each tenancy test case picks which resource to use based on the resource type's scope. - _, err = client.Read(tc.ctx, &pbresource.ReadRequest{Id: tenancyCase.modFn(artist.Id, recordLabel.Id)}) + _, err = client.Read(tc.ctx, &pbresource.ReadRequest{Id: modFn(artist.Id, recordLabel.Id)}) require.Error(t, err) require.Equal(t, codes.NotFound.String(), status.Code(err).String()) - require.ErrorContains(t, err, tenancyCase.errContains) + require.Contains(t, err.Error(), "resource not found") }) } }) @@ -261,7 +176,7 @@ func TestRead_Success(t *testing.T) { demo.RegisterTypes(server.Registry) client := testClient(t, server) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) recordLabel, err = server.Backend.WriteCAS(tc.ctx, recordLabel) require.NoError(t, err) diff --git a/agent/grpc-external/services/resource/server.go b/agent/grpc-external/services/resource/server.go index e2615ec4b3bae..5fc5a01fafd77 100644 --- a/agent/grpc-external/services/resource/server.go +++ b/agent/grpc-external/services/resource/server.go @@ -5,7 +5,6 @@ package resource import ( "context" - "strings" "github.com/hashicorp/go-hclog" "google.golang.org/grpc" @@ -35,11 +34,6 @@ type Config struct { // TenancyBridge temporarily allows us to use V1 implementations of // partitions and namespaces until V2 implementations are available. TenancyBridge TenancyBridge - - // UseV2Tenancy is true if the "v2tenancy" experiement is active, false otherwise. - // Attempts to create v2 tenancy resources (partition or namespace) will fail when the - // flag is false. - UseV2Tenancy bool } //go:generate mockery --name Registry --inpackage @@ -135,12 +129,16 @@ func isGRPCStatusError(err error) bool { } func validateId(id *pbresource.ID, errorPrefix string) error { - if id.Type == nil { - return status.Errorf(codes.InvalidArgument, "%s.type is required", errorPrefix) + var field string + switch { + case id.Type == nil: + field = "type" + case id.Name == "": + field = "name" } - if err := resource.ValidateName(id.Name); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.name invalid: %v", errorPrefix, err) + if field != "" { + return status.Errorf(codes.InvalidArgument, "%s.%s is required", errorPrefix, field) } // Better UX: Allow callers to pass in nil tenancy. Defaulting and inheritance of tenancy @@ -154,128 +152,39 @@ func validateId(id *pbresource.ID, errorPrefix string) error { } } - if id.Tenancy.Partition != "" { - if err := resource.ValidateName(id.Tenancy.Partition); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.tenancy.partition invalid: %v", errorPrefix, err) - } - } - if id.Tenancy.Namespace != "" { - if err := resource.ValidateName(id.Tenancy.Namespace); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.tenancy.namespace invalid: %v", errorPrefix, err) - } - } - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - if id.Tenancy.PeerName == "" { - id.Tenancy.PeerName = resource.DefaultPeerName - } + resource.Normalize(id.Tenancy) return nil } -func validateRef(ref *pbresource.Reference, errorPrefix string) error { - if ref.Type == nil { - return status.Errorf(codes.InvalidArgument, "%s.type is required", errorPrefix) - } - if err := resource.ValidateName(ref.Name); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.name invalid: %v", errorPrefix, err) - } - if err := resource.ValidateName(ref.Tenancy.Partition); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.tenancy.partition invalid: %v", errorPrefix, err) - } - if err := resource.ValidateName(ref.Tenancy.Namespace); err != nil { - return status.Errorf(codes.InvalidArgument, "%s.tenancy.namespace invalid: %v", errorPrefix, err) - } - return nil -} - -func validateWildcardTenancy(tenancy *pbresource.Tenancy, namePrefix string) error { - // Partition has to be a valid name if not wildcard or empty - if tenancy.Partition != "" && tenancy.Partition != "*" { - if err := resource.ValidateName(tenancy.Partition); err != nil { - return status.Errorf(codes.InvalidArgument, "tenancy.partition invalid: %v", err) - } - } - - // Namespace has to be a valid name if not wildcard or empty - if tenancy.Namespace != "" && tenancy.Namespace != "*" { - if err := resource.ValidateName(tenancy.Namespace); err != nil { - return status.Errorf(codes.InvalidArgument, "tenancy.namespace invalid: %v", err) - } - } - - // Not doing a strict resource name validation here because the prefix can be - // something like "foo-" which is a valid prefix but not valid resource name. - // relax validation to just check for lowercasing - if namePrefix != strings.ToLower(namePrefix) { - return status.Errorf(codes.InvalidArgument, "name_prefix invalid: must be lowercase alphanumeric, got: %v", namePrefix) - } - - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - if tenancy.PeerName == "" { - tenancy.PeerName = resource.DefaultPeerName - } - - return nil -} - -// tenancyExists return an error with the passed in gRPC status code when tenancy partition or namespace do not exist. -func tenancyExists(reg *resource.Registration, tenancyBridge TenancyBridge, tenancy *pbresource.Tenancy, errCode codes.Code) error { +// v1TenancyExists return an error with the passed in gRPC status code when tenancy partition or namespace do not exist. +func v1TenancyExists(reg *resource.Registration, v1Bridge TenancyBridge, tenancy *pbresource.Tenancy, errCode codes.Code) error { if reg.Scope == resource.ScopePartition || reg.Scope == resource.ScopeNamespace { - exists, err := tenancyBridge.PartitionExists(tenancy.Partition) + exists, err := v1Bridge.PartitionExists(tenancy.Partition) switch { case err != nil: return err case !exists: - return status.Errorf(errCode, "partition not found: %v", tenancy.Partition) + return status.Errorf(errCode, "partition resource not found: %v", tenancy.Partition) } } if reg.Scope == resource.ScopeNamespace { - exists, err := tenancyBridge.NamespaceExists(tenancy.Partition, tenancy.Namespace) + exists, err := v1Bridge.NamespaceExists(tenancy.Partition, tenancy.Namespace) switch { case err != nil: return err case !exists: - return status.Errorf(errCode, "namespace not found: %v", tenancy.Namespace) - } - } - return nil -} - -func validateScopedTenancy(scope resource.Scope, resourceType *pbresource.Type, tenancy *pbresource.Tenancy) error { - if scope == resource.ScopePartition && tenancy.Namespace != "" { - return status.Errorf( - codes.InvalidArgument, - "partition scoped resource %s cannot have a namespace. got: %s", - resource.ToGVK(resourceType), - tenancy.Namespace, - ) - } - if scope == resource.ScopeCluster { - if tenancy.Partition != "" { - return status.Errorf( - codes.InvalidArgument, - "cluster scoped resource %s cannot have a partition: %s", - resource.ToGVK(resourceType), - tenancy.Partition, - ) - } - if tenancy.Namespace != "" { - return status.Errorf( - codes.InvalidArgument, - "cluster scoped resource %s cannot have a namespace: %s", - resource.ToGVK(resourceType), - tenancy.Namespace, - ) + return status.Errorf(errCode, "namespace resource not found: %v", tenancy.Namespace) } } return nil } -// tenancyMarkedForDeletion returns a gRPC InvalidArgument when either partition or namespace is marked for deletion. -func tenancyMarkedForDeletion(reg *resource.Registration, tenancyBridge TenancyBridge, tenancy *pbresource.Tenancy) error { +// v1TenancyMarkedForDeletion returns a gRPC InvalidArgument when either partition or namespace is marked for deletion. +func v1TenancyMarkedForDeletion(reg *resource.Registration, v1Bridge TenancyBridge, tenancy *pbresource.Tenancy) error { if reg.Scope == resource.ScopePartition || reg.Scope == resource.ScopeNamespace { - marked, err := tenancyBridge.IsPartitionMarkedForDeletion(tenancy.Partition) + marked, err := v1Bridge.IsPartitionMarkedForDeletion(tenancy.Partition) switch { case err != nil: return err @@ -285,7 +194,7 @@ func tenancyMarkedForDeletion(reg *resource.Registration, tenancyBridge TenancyB } if reg.Scope == resource.ScopeNamespace { - marked, err := tenancyBridge.IsNamespaceMarkedForDeletion(tenancy.Partition, tenancy.Namespace) + marked, err := v1Bridge.IsNamespaceMarkedForDeletion(tenancy.Partition, tenancy.Namespace) switch { case err != nil: return err diff --git a/agent/grpc-external/services/resource/server_ce.go b/agent/grpc-external/services/resource/server_ce.go index 2e3f792fe1d10..bc48194574131 100644 --- a/agent/grpc-external/services/resource/server_ce.go +++ b/agent/grpc-external/services/resource/server_ce.go @@ -6,13 +6,9 @@ package resource import ( - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" ) func v2TenancyToV1EntMeta(tenancy *pbresource.Tenancy) *acl.EnterpriseMeta { @@ -28,12 +24,3 @@ func v1EntMetaToV2Tenancy(reg *resource.Registration, entMeta *acl.EnterpriseMet tenancy.Namespace = entMeta.NamespaceOrDefault() } } - -// checkV2Tenancy returns FailedPrecondition error for namespace resource type -// when the "v2tenancy" feature flag is not enabled. -func checkV2Tenancy(useV2Tenancy bool, rtype *pbresource.Type) error { - if resource.EqualType(rtype, pbtenancy.NamespaceType) && !useV2Tenancy { - return status.Errorf(codes.FailedPrecondition, "use of the v2 namespace resource requires the \"v2tenancy\" feature flag") - } - return nil -} diff --git a/agent/grpc-external/services/resource/server_test.go b/agent/grpc-external/services/resource/server_test.go index e0b52263901fe..99add64971218 100644 --- a/agent/grpc-external/services/resource/server_test.go +++ b/agent/grpc-external/services/resource/server_test.go @@ -6,6 +6,7 @@ package resource import ( "context" "fmt" + "strings" "testing" "github.com/stretchr/testify/mock" @@ -75,7 +76,7 @@ func testServer(t *testing.T) *Server { } }) - // Mock the tenancy bridge since we can't use the real thing. + // Mock the V1 tenancy bridge since we can't use the real thing. mockTenancyBridge := &MockTenancyBridge{} mockTenancyBridge.On("PartitionExists", resource.DefaultPartitionName).Return(true, nil) mockTenancyBridge.On("NamespaceExists", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(true, nil) @@ -157,20 +158,19 @@ func wildcardTenancyCases() map[string]struct { PeerName: "local", }, }, - // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy - "namespaced type with empty peername": { + "namespaced type with empty partition and namespace": { typ: demo.TypeV2Artist, tenancy: &pbresource.Tenancy{ - Partition: resource.DefaultPartitionName, - Namespace: resource.DefaultNamespaceName, - PeerName: "", + Partition: "", + Namespace: "", + PeerName: "local", }, }, - "namespaced type with empty partition and namespace": { + "namespaced type with uppercase partition and namespace": { typ: demo.TypeV2Artist, tenancy: &pbresource.Tenancy{ - Partition: "", - Namespace: "", + Partition: "DEFAULT", + Namespace: "DEFAULT", PeerName: "local", }, }, @@ -198,6 +198,14 @@ func wildcardTenancyCases() map[string]struct { PeerName: "local", }, }, + "partitioned type with uppercase partition": { + typ: demo.TypeV1RecordLabel, + tenancy: &pbresource.Tenancy{ + Partition: "DEFAULT", + Namespace: "", + PeerName: "local", + }, + }, "partitioned type with wildcard partition": { typ: demo.TypeV1RecordLabel, tenancy: &pbresource.Tenancy{ @@ -216,6 +224,12 @@ func tenancyCases() map[string]func(artistId, recordlabelId *pbresource.ID) *pbr "namespaced resource provides nonempty partition and namespace": func(artistId, recordLabelId *pbresource.ID) *pbresource.ID { return artistId }, + "namespaced resource provides uppercase partition and namespace": func(artistId, _ *pbresource.ID) *pbresource.ID { + id := clone(artistId) + id.Tenancy.Partition = strings.ToUpper(artistId.Tenancy.Partition) + id.Tenancy.Namespace = strings.ToUpper(artistId.Tenancy.Namespace) + return id + }, "namespaced resource inherits tokens partition when empty": func(artistId, _ *pbresource.ID) *pbresource.ID { id := clone(artistId) id.Tenancy.Partition = "" @@ -240,6 +254,11 @@ func tenancyCases() map[string]func(artistId, recordlabelId *pbresource.ID) *pbr "partitioned resource provides nonempty partition": func(_, recordLabelId *pbresource.ID) *pbresource.ID { return recordLabelId }, + "partitioned resource provides uppercase partition": func(_, recordLabelId *pbresource.ID) *pbresource.ID { + id := clone(recordLabelId) + id.Tenancy.Partition = strings.ToUpper(recordLabelId.Tenancy.Partition) + return id + }, "partitioned resource inherits tokens partition when empty": func(_, recordLabelId *pbresource.ID) *pbresource.ID { id := clone(recordLabelId) id.Tenancy.Partition = "" diff --git a/agent/grpc-external/services/resource/testing/testing.go b/agent/grpc-external/services/resource/testing/testing.go index c9f03bea1a259..2375ae95b8894 100644 --- a/agent/grpc-external/services/resource/testing/testing.go +++ b/agent/grpc-external/services/resource/testing/testing.go @@ -7,12 +7,13 @@ import ( "context" "testing" - "github.com/hashicorp/go-uuid" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" svc "github.com/hashicorp/consul/agent/grpc-external/services/resource" @@ -21,7 +22,6 @@ import ( "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/storage/inmem" - "github.com/hashicorp/consul/internal/tenancy" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil" ) @@ -94,17 +94,10 @@ func RunResourceServiceWithConfig(t *testing.T, config svc.Config, registerFns . mockTenancyBridge.On("PartitionExists", resource.DefaultPartitionName).Return(true, nil) mockTenancyBridge.On("PartitionExists", "foo").Return(true, nil) mockTenancyBridge.On("NamespaceExists", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(true, nil) - mockTenancyBridge.On("PartitionExists", "foo").Return(true, nil) mockTenancyBridge.On("IsPartitionMarkedForDeletion", resource.DefaultPartitionName).Return(false, nil) mockTenancyBridge.On("IsPartitionMarkedForDeletion", "foo").Return(false, nil) mockTenancyBridge.On("IsNamespaceMarkedForDeletion", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(false, nil) config.TenancyBridge = mockTenancyBridge - } else { - switch config.TenancyBridge.(type) { - case *tenancy.V2TenancyBridge: - err = initTenancy(ctx, backend) - require.NoError(t, err) - } } if config.ACLResolver == nil { @@ -147,14 +140,6 @@ func RunResourceServiceWithConfig(t *testing.T, config svc.Config, registerFns . ) require.NoError(t, err) t.Cleanup(func() { _ = conn.Close() }) - client := pbresource.NewResourceServiceClient(conn) - if config.TenancyBridge != nil { - switch config.TenancyBridge.(type) { - case *tenancy.V2TenancyBridge: - config.TenancyBridge.(*tenancy.V2TenancyBridge).WithClient(client) - } - - } - return client + return pbresource.NewResourceServiceClient(conn) } diff --git a/agent/grpc-external/services/resource/testing/testing_ce.go b/agent/grpc-external/services/resource/testing/testing_ce.go index da20be3533d44..023fa5189cccc 100644 --- a/agent/grpc-external/services/resource/testing/testing_ce.go +++ b/agent/grpc-external/services/resource/testing/testing_ce.go @@ -6,19 +6,7 @@ package testing import ( - "context" - "errors" - "time" - - "github.com/oklog/ulid/v2" - "google.golang.org/protobuf/types/known/anypb" - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/storage" - "github.com/hashicorp/consul/internal/storage/inmem" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" ) func FillEntMeta(entMeta *acl.EnterpriseMeta) { @@ -28,38 +16,3 @@ func FillEntMeta(entMeta *acl.EnterpriseMeta) { func FillAuthorizerContext(authzContext *acl.AuthorizerContext) { // nothing to to in CE. } - -// initTenancy create the base tenancy objects (default/default) -func initTenancy(ctx context.Context, b *inmem.Backend) error { - //TODO(dhiaayachi): This is now called for testing purpose but at some point we need to add something similar - // when bootstrapping a server, probably in the tenancy controllers. - nsData, err := anypb.New(&pbtenancy.Namespace{Description: "default namespace in default partition"}) - if err != nil { - return err - } - nsID := &pbresource.ID{ - Type: pbtenancy.NamespaceType, - Name: resource.DefaultNamespaceName, - Tenancy: resource.DefaultPartitionedTenancy(), - Uid: ulid.Make().String(), - } - read, err := b.Read(ctx, storage.StrongConsistency, nsID) - if err != nil && !errors.Is(err, storage.ErrNotFound) { - return err - } - if read == nil && errors.Is(err, storage.ErrNotFound) { - _, err = b.WriteCAS(ctx, &pbresource.Resource{ - Id: nsID, - Generation: ulid.Make().String(), - Data: nsData, - Metadata: map[string]string{ - "generated_at": time.Now().Format(time.RFC3339), - }, - }) - if err != nil { - return err - } - } - return nil - -} diff --git a/agent/grpc-external/services/resource/watch.go b/agent/grpc-external/services/resource/watch.go index adabb3d256ee0..f20d3f00f875a 100644 --- a/agent/grpc-external/services/resource/watch.go +++ b/agent/grpc-external/services/resource/watch.go @@ -16,7 +16,7 @@ import ( ) func (s *Server) WatchList(req *pbresource.WatchListRequest, stream pbresource.ResourceService_WatchListServer) error { - reg, err := s.ensureWatchListRequestValid(req) + reg, err := s.validateWatchListRequest(req) if err != nil { return err } @@ -91,9 +91,17 @@ func (s *Server) WatchList(req *pbresource.WatchListRequest, stream pbresource.R } } -func (s *Server) ensureWatchListRequestValid(req *pbresource.WatchListRequest) (*resource.Registration, error) { - if req.Type == nil { - return nil, status.Errorf(codes.InvalidArgument, "type is required") +func (s *Server) validateWatchListRequest(req *pbresource.WatchListRequest) (*resource.Registration, error) { + var field string + switch { + case req.Type == nil: + field = "type" + case req.Tenancy == nil: + field = "tenancy" + } + + if field != "" { + return nil, status.Errorf(codes.InvalidArgument, "%s is required", field) } // Check type exists. @@ -102,46 +110,18 @@ func (s *Server) ensureWatchListRequestValid(req *pbresource.WatchListRequest) ( return nil, err } - // if no tenancy is passed defaults to wildcard - if req.Tenancy == nil { - req.Tenancy = wildcardTenancyFor(reg.Scope) - } - - if err = checkV2Tenancy(s.UseV2Tenancy, req.Type); err != nil { - return nil, err - } - - if err := validateWildcardTenancy(req.Tenancy, req.NamePrefix); err != nil { - return nil, err - } - - // Check scope - if err = validateScopedTenancy(reg.Scope, req.Type, req.Tenancy); err != nil { - return nil, err + // Lowercase + resource.Normalize(req.Tenancy) + + // Error when partition scoped and namespace not empty. + if reg.Scope == resource.ScopePartition && req.Tenancy.Namespace != "" { + return nil, status.Errorf( + codes.InvalidArgument, + "partition scoped type %s cannot have a namespace. got: %s", + resource.ToGVK(req.Type), + req.Tenancy.Namespace, + ) } return reg, nil } - -func wildcardTenancyFor(scope resource.Scope) *pbresource.Tenancy { - var defaultTenancy *pbresource.Tenancy - - switch scope { - case resource.ScopeCluster: - defaultTenancy = &pbresource.Tenancy{ - PeerName: storage.Wildcard, - } - case resource.ScopePartition: - defaultTenancy = &pbresource.Tenancy{ - Partition: storage.Wildcard, - PeerName: storage.Wildcard, - } - default: - defaultTenancy = &pbresource.Tenancy{ - Partition: storage.Wildcard, - PeerName: storage.Wildcard, - Namespace: storage.Wildcard, - } - } - return defaultTenancy -} diff --git a/agent/grpc-external/services/resource/watch_test.go b/agent/grpc-external/services/resource/watch_test.go index 1c9da4b68d0d4..051264441bbc8 100644 --- a/agent/grpc-external/services/resource/watch_test.go +++ b/agent/grpc-external/services/resource/watch_test.go @@ -7,7 +7,6 @@ import ( "context" "errors" "io" - "strings" "testing" "time" @@ -28,71 +27,24 @@ import ( func TestWatchList_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(*pbresource.WatchListRequest) - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no type": { - modFn: func(req *pbresource.WatchListRequest) { req.Type = nil }, - errContains: "type is required", - }, - "partition mixed case": { - modFn: func(req *pbresource.WatchListRequest) { req.Tenancy.Partition = "Default" }, - errContains: "tenancy.partition invalid", - }, - "partition too long": { - modFn: func(req *pbresource.WatchListRequest) { - req.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errContains: "tenancy.partition invalid", - }, - "namespace mixed case": { - modFn: func(req *pbresource.WatchListRequest) { req.Tenancy.Namespace = "Default" }, - errContains: "tenancy.namespace invalid", - }, - "namespace too long": { - modFn: func(req *pbresource.WatchListRequest) { - req.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errContains: "tenancy.namespace invalid", - }, - "name_prefix mixed case": { - modFn: func(req *pbresource.WatchListRequest) { req.NamePrefix = "Smashing" }, - errContains: "name_prefix invalid", - }, - "partitioned type provides non-empty namespace": { - modFn: func(req *pbresource.WatchListRequest) { - req.Type = demo.TypeV1RecordLabel - req.Tenancy.Namespace = "bad" - }, - errContains: "cannot have a namespace", - }, - "cluster scope with non-empty partition": { - modFn: func(req *pbresource.WatchListRequest) { - req.Type = demo.TypeV1Executive - req.Tenancy = &pbresource.Tenancy{Partition: "bad"} - }, - errContains: "cannot have a partition", - }, - "cluster scope with non-empty namespace": { - modFn: func(req *pbresource.WatchListRequest) { - req.Type = demo.TypeV1Executive - req.Tenancy = &pbresource.Tenancy{Namespace: "bad"} - }, - errContains: "cannot have a namespace", + testCases := map[string]func(*pbresource.WatchListRequest){ + "no type": func(req *pbresource.WatchListRequest) { req.Type = nil }, + "no tenancy": func(req *pbresource.WatchListRequest) { req.Tenancy = nil }, + "partitioned type provides non-empty namespace": func(req *pbresource.WatchListRequest) { + req.Type = demo.TypeV1RecordLabel + req.Tenancy.Namespace = "bad" }, } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { req := &pbresource.WatchListRequest{ Type: demo.TypeV2Album, Tenancy: resource.DefaultNamespacedTenancy(), } - tc.modFn(req) + modFn(req) stream, err := client.WatchList(testContext(t), req) require.NoError(t, err) @@ -100,7 +52,6 @@ func TestWatchList_InputValidation(t *testing.T) { _, err = stream.Recv() require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -185,7 +136,7 @@ func TestWatchList_Tenancy_Defaults_And_Normalization(t *testing.T) { rspCh := handleResourceStream(t, stream) // Testcase will pick one of recordLabel or artist based on scope of type. - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LooneyTunes") require.NoError(t, err) artist, err := demo.GenerateV2Artist() require.NoError(t, err) @@ -392,30 +343,3 @@ type resourceOrError struct { rsp *pbresource.WatchEvent err error } - -func TestWatchList_NoTenancy(t *testing.T) { - t.Parallel() - ctx := context.Background() - server := testServer(t) - client := testClient(t, server) - demo.RegisterTypes(server.Registry) - - // Create a watch. - stream, err := client.WatchList(ctx, &pbresource.WatchListRequest{ - Type: demo.TypeV1RecordLabel, - }) - require.NoError(t, err) - rspCh := handleResourceStream(t, stream) - - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") - require.NoError(t, err) - - // Create and verify upsert event received. - recordLabel, err = server.Backend.WriteCAS(ctx, recordLabel) - require.NoError(t, err) - - rsp := mustGetResource(t, rspCh) - - require.Equal(t, pbresource.WatchEvent_OPERATION_UPSERT, rsp.Operation) - prototest.AssertDeepEqual(t, recordLabel, rsp.Resource) -} diff --git a/agent/grpc-external/services/resource/write.go b/agent/grpc-external/services/resource/write.go index 63c87f11a18ac..7110122313fa3 100644 --- a/agent/grpc-external/services/resource/write.go +++ b/agent/grpc-external/services/resource/write.go @@ -37,7 +37,7 @@ import ( var errUseWriteStatus = status.Error(codes.InvalidArgument, "resource.status can only be set using the WriteStatus endpoint") func (s *Server) Write(ctx context.Context, req *pbresource.WriteRequest) (*pbresource.WriteResponse, error) { - reg, err := s.ensureWriteRequestValid(req) + reg, err := s.validateWriteRequest(req) if err != nil { return nil, err } @@ -78,13 +78,13 @@ func (s *Server) Write(ctx context.Context, req *pbresource.WriteRequest) (*pbre return nil, status.Errorf(codes.Internal, "failed write acl: %v", err) } - // Check tenancy exists for the V2 resource - if err = tenancyExists(reg, s.TenancyBridge, req.Resource.Id.Tenancy, codes.InvalidArgument); err != nil { + // Check V1 tenancy exists for the V2 resource + if err = v1TenancyExists(reg, s.TenancyBridge, req.Resource.Id.Tenancy, codes.InvalidArgument); err != nil { return nil, err } - // Check tenancy not marked for deletion. - if err = tenancyMarkedForDeletion(reg, s.TenancyBridge, req.Resource.Id.Tenancy); err != nil { + // Check V1 tenancy not marked for deletion. + if err = v1TenancyMarkedForDeletion(reg, s.TenancyBridge, req.Resource.Id.Tenancy); err != nil { return nil, err } @@ -265,7 +265,7 @@ func (s *Server) retryCAS(ctx context.Context, vsn string, cas func() error) err return err } -func (s *Server) ensureWriteRequestValid(req *pbresource.WriteRequest) (*resource.Registration, error) { +func (s *Server) validateWriteRequest(req *pbresource.WriteRequest) (*resource.Registration, error) { var field string switch { case req.Resource == nil: @@ -294,10 +294,6 @@ func (s *Server) ensureWriteRequestValid(req *pbresource.WriteRequest) (*resourc return nil, err } - if err = checkV2Tenancy(s.UseV2Tenancy, req.Resource.Id.Type); err != nil { - return nil, err - } - // Check scope if reg.Scope == resource.ScopePartition && req.Resource.Id.Tenancy.Namespace != "" { return nil, status.Errorf( diff --git a/agent/grpc-external/services/resource/write_status.go b/agent/grpc-external/services/resource/write_status.go index 7009a7fd72bb2..0d3b68bb08766 100644 --- a/agent/grpc-external/services/resource/write_status.go +++ b/agent/grpc-external/services/resource/write_status.go @@ -34,9 +34,9 @@ func (s *Server) WriteStatus(ctx context.Context, req *pbresource.WriteStatusReq // Apply defaults when tenancy units empty. v1EntMetaToV2Tenancy(reg, entMeta, req.Id.Tenancy) - // Check tenancy exists for the V2 resource. Ignore "marked for deletion" since status updates + // Check V1 tenancy exists for the V2 resource. Ignore "marked for deletion" since status updates // should still work regardless. - if err = tenancyExists(reg, s.TenancyBridge, req.Id.Tenancy, codes.InvalidArgument); err != nil { + if err = v1TenancyExists(reg, s.TenancyBridge, req.Id.Tenancy, codes.InvalidArgument); err != nil { return nil, err } @@ -178,17 +178,8 @@ func (s *Server) validateWriteStatusRequest(req *pbresource.WriteStatusRequest) } } - if err := validateId(req.Id, "id"); err != nil { - return nil, err - } - - for i, condition := range req.Status.Conditions { - if condition.Resource != nil { - if err := validateRef(condition.Resource, fmt.Sprintf("status.conditions[%d].resource", i)); err != nil { - return nil, err - } - } - } + // Lowercase + resource.Normalize(req.Id.Tenancy) // Check type exists. reg, err := s.resolveType(req.Id.Type) diff --git a/agent/grpc-external/services/resource/write_status_test.go b/agent/grpc-external/services/resource/write_status_test.go index 1ddf738632365..5b71983475d94 100644 --- a/agent/grpc-external/services/resource/write_status_test.go +++ b/agent/grpc-external/services/resource/write_status_test.go @@ -74,155 +74,64 @@ func TestWriteStatus_InputValidation(t *testing.T) { demo.RegisterTypes(server.Registry) testCases := map[string]struct { - typ *pbresource.Type - modFn func(req *pbresource.WriteStatusRequest) - errContains string + typ *pbresource.Type + modFn func(req *pbresource.WriteStatusRequest) }{ "no id": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id = nil }, - errContains: "id is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Id = nil }, }, "no type": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Type = nil }, - errContains: "id.type is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Type = nil }, }, "no name": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Name = "" }, - errContains: "id.name is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Name = "" }, }, "no uid": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Uid = "" }, - errContains: "id.uid is required", - }, - "name mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Name = "U2" }, - errContains: "id.name invalid", - }, - "name too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Id.Name = strings.Repeat("a", resource.MaxNameLength+1) - }, - errContains: "id.name invalid", - }, - "partition mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Partition = "Default" }, - errContains: "id.tenancy.partition invalid", - }, - "partition too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Id.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errContains: "id.tenancy.partition invalid", - }, - "namespace mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Namespace = "Default" }, - errContains: "id.tenancy.namespace invalid", - }, - "namespace too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Id.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errContains: "id.tenancy.namespace invalid", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Uid = "" }, }, "no key": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Key = "" }, - errContains: "key is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Key = "" }, }, "no status": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status = nil }, - errContains: "status is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Status = nil }, }, "no observed generation": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.ObservedGeneration = "" }, - errContains: "status.observed_generation is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Status.ObservedGeneration = "" }, }, "bad observed generation": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.ObservedGeneration = "bogus" }, - errContains: "status.observed_generation is not valid", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Status.ObservedGeneration = "bogus" }, }, "no condition type": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Type = "" }, - errContains: "status.conditions[0].type is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Type = "" }, }, "no reference type": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Type = nil }, - errContains: "status.conditions[0].resource.type is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Type = nil }, }, "no reference tenancy": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Tenancy = nil }, - errContains: "status.conditions[0].resource.tenancy is required", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Tenancy = nil }, }, "no reference name": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Name = "" }, - errContains: "status.conditions[0].resource.name is required", - }, - "reference name mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Name = "U2" }, - errContains: "status.conditions[0].resource.name invalid", - }, - "reference name too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Name = strings.Repeat("r", resource.MaxNameLength+1) - }, - errContains: "status.conditions[0].resource.name invalid", - }, - "reference partition mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Tenancy.Partition = "Default" - }, - errContains: "status.conditions[0].resource.tenancy.partition invalid", - }, - "reference partition too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errContains: "status.conditions[0].resource.tenancy.partition invalid", - }, - "reference namespace mixed case": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Tenancy.Namespace = "Default" - }, - errContains: "status.conditions[0].resource.tenancy.namespace invalid", - }, - "reference namespace too long": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { - req.Status.Conditions[0].Resource.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errContains: "status.conditions[0].resource.tenancy.namespace invalid", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Status.Conditions[0].Resource.Name = "" }, }, "updated at provided": { - typ: demo.TypeV2Artist, - modFn: func(req *pbresource.WriteStatusRequest) { req.Status.UpdatedAt = timestamppb.Now() }, - errContains: "status.updated_at is automatically set and cannot be provided", + typ: demo.TypeV2Artist, + modFn: func(req *pbresource.WriteStatusRequest) { req.Status.UpdatedAt = timestamppb.Now() }, }, "partition scoped type provides namespace in tenancy": { - typ: demo.TypeV1RecordLabel, - modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Namespace = "bad" }, - errContains: "cannot have a namespace", + typ: demo.TypeV1RecordLabel, + modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Namespace = "bad" }, }, } for desc, tc := range testCases { @@ -233,7 +142,7 @@ func TestWriteStatus_InputValidation(t *testing.T) { case resource.EqualType(demo.TypeV2Artist, tc.typ): res, err = demo.GenerateV2Artist() case resource.EqualType(demo.TypeV1RecordLabel, tc.typ): - res, err = demo.GenerateV1RecordLabel("looney-tunes") + res, err = demo.GenerateV1RecordLabel("Looney Tunes") default: t.Fatal("unsupported type", tc.typ) } @@ -248,7 +157,6 @@ func TestWriteStatus_InputValidation(t *testing.T) { _, err = client.WriteStatus(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -302,6 +210,13 @@ func TestWriteStatus_Tenancy_Defaults(t *testing.T) { scope: resource.ScopeNamespace, modFn: func(req *pbresource.WriteStatusRequest) {}, }, + "namespaced resource provides uppercase partition and namespace": { + scope: resource.ScopeNamespace, + modFn: func(req *pbresource.WriteStatusRequest) { + req.Id.Tenancy.Partition = strings.ToUpper(req.Id.Tenancy.Partition) + req.Id.Tenancy.Namespace = strings.ToUpper(req.Id.Tenancy.Namespace) + }, + }, "namespaced resource inherits tokens partition when empty": { scope: resource.ScopeNamespace, modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Partition = "" }, @@ -325,6 +240,12 @@ func TestWriteStatus_Tenancy_Defaults(t *testing.T) { scope: resource.ScopePartition, modFn: func(req *pbresource.WriteStatusRequest) {}, }, + "partitioned resource provides uppercase partition": { + scope: resource.ScopePartition, + modFn: func(req *pbresource.WriteStatusRequest) { + req.Id.Tenancy.Partition = strings.ToUpper(req.Id.Tenancy.Partition) + }, + }, "partitioned resource inherits tokens partition when empty": { scope: resource.ScopePartition, modFn: func(req *pbresource.WriteStatusRequest) { req.Id.Tenancy.Partition = "" }, @@ -342,7 +263,7 @@ func TestWriteStatus_Tenancy_Defaults(t *testing.T) { case resource.ScopeNamespace: res, err = demo.GenerateV2Artist() case resource.ScopePartition: - res, err = demo.GenerateV1RecordLabel("looney-tunes") + res, err = demo.GenerateV1RecordLabel("Looney Tunes") } require.NoError(t, err) @@ -359,7 +280,7 @@ func TestWriteStatus_Tenancy_Defaults(t *testing.T) { require.NoError(t, err) res = rsp.Resource - // Re-read resource and verify status successfully written (not nil) + // Re-read resoruce and verify status successfully written (not nil) _, err = client.Read(testContext(t), &pbresource.ReadRequest{Id: res.Id}) require.NoError(t, err) res = rsp.Resource @@ -406,7 +327,7 @@ func TestWriteStatus_Tenancy_NotFound(t *testing.T) { case resource.ScopeNamespace: res, err = demo.GenerateV2Artist() case resource.ScopePartition: - res, err = demo.GenerateV1RecordLabel("looney-tunes") + res, err = demo.GenerateV1RecordLabel("Looney Tunes") } require.NoError(t, err) diff --git a/agent/grpc-external/services/resource/write_test.go b/agent/grpc-external/services/resource/write_test.go index 9f7704b52b97c..3828ff9753f2d 100644 --- a/agent/grpc-external/services/resource/write_test.go +++ b/agent/grpc-external/services/resource/write_test.go @@ -29,123 +29,54 @@ import ( func TestWrite_InputValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) - demo.RegisterTypes(server.Registry) - type testCase struct { - modFn func(artist, recordLabel *pbresource.Resource) *pbresource.Resource - errContains string - } + demo.RegisterTypes(server.Registry) - testCases := map[string]testCase{ - "no resource": { - modFn: func(_, _ *pbresource.Resource) *pbresource.Resource { - return nil - }, - errContains: "resource is required", - }, - "no id": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id = nil - return artist - }, - errContains: "resource.id is required", - }, - "no type": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Type = nil - return artist - }, - errContains: "resource.id.type is required", - }, - "no name": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Name = "" - return artist - }, - errContains: "resource.id.name invalid", - }, - "name is mixed case": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Name = "MixedCaseNotAllowed" - return artist - }, - errContains: "resource.id.name invalid", + testCases := map[string]func(artist, recordLabel *pbresource.Resource) *pbresource.Resource{ + "no resource": func(artist, recordLabel *pbresource.Resource) *pbresource.Resource { return nil }, + "no id": func(artist, _ *pbresource.Resource) *pbresource.Resource { + artist.Id = nil + return artist }, - "name too long": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Name = strings.Repeat("a", resource.MaxNameLength+1) - return artist - }, - errContains: "resource.id.name invalid", - }, - "wrong data type": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - var err error - artist.Data, err = anypb.New(&pbdemov2.Album{}) - require.NoError(t, err) - return artist - }, - errContains: "resource.data is of wrong type", - }, - "partition is mixed case": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Partition = "Default" - return artist - }, - errContains: "resource.id.tenancy.partition invalid", - }, - "partition too long": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - return artist - }, - errContains: "resource.id.tenancy.partition invalid", + "no type": func(artist, _ *pbresource.Resource) *pbresource.Resource { + artist.Id.Type = nil + return artist }, - "namespace is mixed case": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Namespace = "Default" - return artist - }, - errContains: "resource.id.tenancy.namespace invalid", + "no name": func(artist, _ *pbresource.Resource) *pbresource.Resource { + artist.Id.Name = "" + return artist }, - "namespace too long": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - artist.Id.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - return artist - }, - errContains: "resource.id.tenancy.namespace invalid", + "wrong data type": func(artist, _ *pbresource.Resource) *pbresource.Resource { + var err error + artist.Data, err = anypb.New(&pbdemov2.Album{}) + require.NoError(t, err) + return artist }, - "fail validation hook": { - modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { - buffer := &pbdemov2.Artist{} - require.NoError(t, artist.Data.UnmarshalTo(buffer)) - buffer.Name = "" // name cannot be empty - require.NoError(t, artist.Data.MarshalFrom(buffer)) - return artist - }, - errContains: "artist.name required", + "fail validation hook": func(artist, _ *pbresource.Resource) *pbresource.Resource { + buffer := &pbdemov2.Artist{} + require.NoError(t, artist.Data.UnmarshalTo(buffer)) + buffer.Name = "" // name cannot be empty + require.NoError(t, artist.Data.MarshalFrom(buffer)) + return artist }, - "partition scope with non-empty namespace": { - modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { - recordLabel.Id.Tenancy.Namespace = "bogus" - return recordLabel - }, - errContains: "cannot have a namespace", + "partition scope with non-empty namespace": func(_, recordLabel *pbresource.Resource) *pbresource.Resource { + recordLabel.Id.Tenancy.Namespace = "bogus" + return recordLabel }, + // TODO(spatel): add cluster scope tests when we have an actual cluster scoped resource (e.g. partition) } - for desc, tc := range testCases { + for desc, modFn := range testCases { t.Run(desc, func(t *testing.T) { artist, err := demo.GenerateV2Artist() require.NoError(t, err) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) - req := &pbresource.WriteRequest{Resource: tc.modFn(artist, recordLabel)} + req := &pbresource.WriteRequest{Resource: modFn(artist, recordLabel)} _, err = client.Write(testContext(t), req) require.Error(t, err) require.Equal(t, codes.InvalidArgument.String(), status.Code(err).String()) - require.ErrorContains(t, err, tc.errContains) }) } } @@ -153,6 +84,7 @@ func TestWrite_InputValidation(t *testing.T) { func TestWrite_OwnerValidation(t *testing.T) { server := testServer(t) client := testClient(t, server) + demo.RegisterTypes(server.Registry) type testCase struct { @@ -162,49 +94,15 @@ func TestWrite_OwnerValidation(t *testing.T) { testCases := map[string]testCase{ "no owner type": { modReqFn: func(req *pbresource.WriteRequest) { req.Resource.Owner.Type = nil }, - errorContains: "resource.owner.type is required", + errorContains: "resource.owner.type", }, "no owner tenancy": { modReqFn: func(req *pbresource.WriteRequest) { req.Resource.Owner.Tenancy = nil }, - errorContains: "resource.owner does not exist", + errorContains: "resource.owner", }, "no owner name": { modReqFn: func(req *pbresource.WriteRequest) { req.Resource.Owner.Name = "" }, - errorContains: "resource.owner.name invalid", - }, - "mixed case owner name": { - modReqFn: func(req *pbresource.WriteRequest) { req.Resource.Owner.Name = strings.ToUpper(req.Resource.Owner.Name) }, - errorContains: "resource.owner.name invalid", - }, - "owner name too long": { - modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Name = strings.Repeat("a", resource.MaxNameLength+1) - }, - errorContains: "resource.owner.name invalid", - }, - "owner partition is mixed case": { - modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Tenancy.Partition = "Default" - }, - errorContains: "resource.owner.tenancy.partition invalid", - }, - "owner partition too long": { - modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Tenancy.Partition = strings.Repeat("p", resource.MaxNameLength+1) - }, - errorContains: "resource.owner.tenancy.partition invalid", - }, - "owner namespace is mixed case": { - modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Tenancy.Namespace = "Default" - }, - errorContains: "resource.owner.tenancy.namespace invalid", - }, - "owner namespace too long": { - modReqFn: func(req *pbresource.WriteRequest) { - req.Resource.Owner.Tenancy.Namespace = strings.Repeat("n", resource.MaxNameLength+1) - }, - errorContains: "resource.owner.tenancy.namespace invalid", + errorContains: "resource.owner.name", }, } for desc, tc := range testCases { @@ -317,6 +215,14 @@ func TestWrite_Create_Success(t *testing.T) { }, expectedTenancy: resource.DefaultNamespacedTenancy(), }, + "namespaced resource provides uppercase partition and namespace": { + modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { + artist.Id.Tenancy.Partition = strings.ToUpper(artist.Id.Tenancy.Partition) + artist.Id.Tenancy.Namespace = strings.ToUpper(artist.Id.Tenancy.Namespace) + return artist + }, + expectedTenancy: resource.DefaultNamespacedTenancy(), + }, "namespaced resource inherits tokens partition when empty": { modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { artist.Id.Tenancy.Partition = "" @@ -360,6 +266,13 @@ func TestWrite_Create_Success(t *testing.T) { }, expectedTenancy: resource.DefaultPartitionedTenancy(), }, + "partitioned resource provides uppercase partition": { + modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { + recordLabel.Id.Tenancy.Partition = strings.ToUpper(recordLabel.Id.Tenancy.Partition) + return recordLabel + }, + expectedTenancy: resource.DefaultPartitionedTenancy(), + }, "partitioned resource inherits tokens partition when empty": { modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { recordLabel.Id.Tenancy.Partition = "" @@ -390,7 +303,7 @@ func TestWrite_Create_Success(t *testing.T) { client := testClient(t, server) demo.RegisterTypes(server.Registry) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) artist, err := demo.GenerateV2Artist() @@ -418,7 +331,7 @@ func TestWrite_Create_Tenancy_NotFound(t *testing.T) { return artist }, errCode: codes.InvalidArgument, - errContains: "partition not found", + errContains: "partition", }, "namespaced resource provides nonexistant namespace": { modFn: func(artist, _ *pbresource.Resource) *pbresource.Resource { @@ -426,7 +339,7 @@ func TestWrite_Create_Tenancy_NotFound(t *testing.T) { return artist }, errCode: codes.InvalidArgument, - errContains: "namespace not found", + errContains: "namespace", }, "partitioned resource provides nonexistant partition": { modFn: func(_, recordLabel *pbresource.Resource) *pbresource.Resource { @@ -434,7 +347,7 @@ func TestWrite_Create_Tenancy_NotFound(t *testing.T) { return recordLabel }, errCode: codes.InvalidArgument, - errContains: "partition not found", + errContains: "partition", }, } for desc, tc := range testCases { @@ -443,7 +356,7 @@ func TestWrite_Create_Tenancy_NotFound(t *testing.T) { client := testClient(t, server) demo.RegisterTypes(server.Registry) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) artist, err := demo.GenerateV2Artist() @@ -465,22 +378,22 @@ func TestWrite_Tenancy_MarkedForDeletion(t *testing.T) { }{ "namespaced resources partition marked for deletion": { modFn: func(artist, _ *pbresource.Resource, mockTenancyBridge *MockTenancyBridge) *pbresource.Resource { - mockTenancyBridge.On("IsPartitionMarkedForDeletion", "ap1").Return(true, nil) + mockTenancyBridge.On("IsPartitionMarkedForDeletion", "part1").Return(true, nil) return artist }, errContains: "partition marked for deletion", }, "namespaced resources namespace marked for deletion": { modFn: func(artist, _ *pbresource.Resource, mockTenancyBridge *MockTenancyBridge) *pbresource.Resource { - mockTenancyBridge.On("IsPartitionMarkedForDeletion", "ap1").Return(false, nil) - mockTenancyBridge.On("IsNamespaceMarkedForDeletion", "ap1", "ns1").Return(true, nil) + mockTenancyBridge.On("IsPartitionMarkedForDeletion", "part1").Return(false, nil) + mockTenancyBridge.On("IsNamespaceMarkedForDeletion", "part1", "ns1").Return(true, nil) return artist }, errContains: "namespace marked for deletion", }, "partitioned resources partition marked for deletion": { modFn: func(_, recordLabel *pbresource.Resource, mockTenancyBridge *MockTenancyBridge) *pbresource.Resource { - mockTenancyBridge.On("IsPartitionMarkedForDeletion", "ap1").Return(true, nil) + mockTenancyBridge.On("IsPartitionMarkedForDeletion", "part1").Return(true, nil) return recordLabel }, errContains: "partition marked for deletion", @@ -491,18 +404,18 @@ func TestWrite_Tenancy_MarkedForDeletion(t *testing.T) { server := testServer(t) client := testClient(t, server) demo.RegisterTypes(server.Registry) - recordLabel, err := demo.GenerateV1RecordLabel("looney-tunes") + recordLabel, err := demo.GenerateV1RecordLabel("LoonyTunes") require.NoError(t, err) - recordLabel.Id.Tenancy.Partition = "ap1" + recordLabel.Id.Tenancy.Partition = "part1" artist, err := demo.GenerateV2Artist() require.NoError(t, err) - artist.Id.Tenancy.Partition = "ap1" + artist.Id.Tenancy.Partition = "part1" artist.Id.Tenancy.Namespace = "ns1" mockTenancyBridge := &MockTenancyBridge{} - mockTenancyBridge.On("PartitionExists", "ap1").Return(true, nil) - mockTenancyBridge.On("NamespaceExists", "ap1", "ns1").Return(true, nil) + mockTenancyBridge.On("PartitionExists", "part1").Return(true, nil) + mockTenancyBridge.On("NamespaceExists", "part1", "ns1").Return(true, nil) server.TenancyBridge = mockTenancyBridge _, err = client.Write(testContext(t), &pbresource.WriteRequest{Resource: tc.modFn(artist, recordLabel, mockTenancyBridge)}) diff --git a/agent/structs/structs.go b/agent/structs/structs.go index 9b2685946cbeb..5a6fd95118920 100644 --- a/agent/structs/structs.go +++ b/agent/structs/structs.go @@ -10,7 +10,6 @@ import ( "encoding/json" "fmt" "math/rand" - "os" "reflect" "regexp" "sort" @@ -228,9 +227,6 @@ const ( var allowedConsulMetaKeysForMeshGateway = map[string]struct{}{MetaWANFederationKey: {}} -// CEDowngrade indicates if we are in downgrading from ent to ce -var CEDowngrade = os.Getenv("CONSUL_ENTERPRISE_DOWNGRADE_TO_CE") == "true" - var ( NodeMaintCheckID = NewCheckID(NodeMaint, nil) ) diff --git a/agent/xds/clusters_test.go b/agent/xds/clusters_test.go index ff6b0f70fc7ce..fb92ea5804b6f 100644 --- a/agent/xds/clusters_test.go +++ b/agent/xds/clusters_test.go @@ -68,6 +68,13 @@ func makeClusterDiscoChainTests(enterprise bool) []clusterTestCase { // TODO(proxystate): requires custom cluster work alsoRunTestForV2: false, }, + { + name: "connect-proxy-with-chain", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", enterprise, nil, nil) + }, + alsoRunTestForV2: true, + }, { name: "connect-proxy-with-chain-http2", create: func(t testinf.T) *proxycfg.ConfigSnapshot { @@ -77,6 +84,14 @@ func makeClusterDiscoChainTests(enterprise bool) []clusterTestCase { }, alsoRunTestForV2: true, }, + { + name: "connect-proxy-with-chain-external-sni", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) + }, + //TODO(proxystate): this requires terminating gateway work + alsoRunTestForV2: true, + }, { name: "connect-proxy-with-chain-and-overrides", create: func(t testinf.T) *proxycfg.ConfigSnapshot { @@ -90,7 +105,7 @@ func makeClusterDiscoChainTests(enterprise bool) []clusterTestCase { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover", enterprise, nil, nil) }, // TODO(proxystate): requires routes work - alsoRunTestForV2: true, + alsoRunTestForV2: false, }, { name: "connect-proxy-with-tcp-chain-failover-through-remote-gateway", diff --git a/agent/xds/endpoints_test.go b/agent/xds/endpoints_test.go index f16327f88b05c..9daf5b31f55b3 100644 --- a/agent/xds/endpoints_test.go +++ b/agent/xds/endpoints_test.go @@ -247,6 +247,34 @@ type endpointTestCase struct { func makeEndpointDiscoChainTests(enterprise bool) []endpointTestCase { return []endpointTestCase{ + { + name: "connect-proxy-with-chain", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", enterprise, nil, nil) + }, + alsoRunTestForV2: true, + }, + { + name: "connect-proxy-with-chain-external-sni", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) + }, + alsoRunTestForV2: true, + }, + { + name: "connect-proxy-with-chain-and-overrides", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple-with-overrides", enterprise, nil, nil) + }, + alsoRunTestForV2: true, + }, + { + name: "connect-proxy-with-chain-and-failover", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover", enterprise, nil, nil) + }, + alsoRunTestForV2: true, + }, { name: "connect-proxy-with-tcp-chain-failover-through-remote-gateway", create: func(t testinf.T) *proxycfg.ConfigSnapshot { diff --git a/agent/xds/listeners_test.go b/agent/xds/listeners_test.go index dfe088f57787a..ff538342f78fd 100644 --- a/agent/xds/listeners_test.go +++ b/agent/xds/listeners_test.go @@ -124,6 +124,13 @@ func makeListenerDiscoChainTests(enterprise bool) []listenerTestCase { }, alsoRunTestForV2: true, }, + { + name: "connect-proxy-with-chain-external-sni", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) + }, + alsoRunTestForV2: true, + }, { name: "connect-proxy-with-chain-and-overrides", create: func(t testinf.T) *proxycfg.ConfigSnapshot { diff --git a/agent/xds/proxystateconverter/clusters.go b/agent/xds/proxystateconverter/clusters.go index fa3a5eadd884a..b8857bee29c59 100644 --- a/agent/xds/proxystateconverter/clusters.go +++ b/agent/xds/proxystateconverter/clusters.go @@ -864,7 +864,6 @@ func (s *Converter) makeUpstreamClustersForDiscoveryChain( failoverGroup = &pbproxystate.FailoverGroup{ Config: &pbproxystate.FailoverGroupConfig{ ConnectTimeout: durationpb.New(node.Resolver.ConnectTimeout), - UseAltStatName: true, }, } } @@ -928,7 +927,6 @@ func (s *Converter) makeUpstreamClustersForDiscoveryChain( Group: &pbproxystate.EndpointGroup_Dynamic{ Dynamic: dynamic, }, - Name: groupedTarget.ClusterName, } endpointGroups = append(endpointGroups, eg) } else { @@ -942,7 +940,6 @@ func (s *Converter) makeUpstreamClustersForDiscoveryChain( }, }, }, - Name: mappedTargets.baseClusterName, } out[mappedTargets.baseClusterName] = cluster diff --git a/agent/xds/proxystateconverter/failover_policy.go b/agent/xds/proxystateconverter/failover_policy.go index 2b0c0617c6bf2..ae1565458fa82 100644 --- a/agent/xds/proxystateconverter/failover_policy.go +++ b/agent/xds/proxystateconverter/failover_policy.go @@ -124,6 +124,22 @@ func (s *Converter) mapDiscoChainTargets(cfgSnap *proxycfg.ConfigSnapshot, chain Service: target.Service, }.URI().String()} } + //commonTLSContext := makeCommonTLSContext( + // cfgSnap.Leaf(), + // rootPEMs, + // makeTLSParametersFromProxyTLSConfig(cfgSnap.MeshConfigTLSOutgoing()), + //) + // + //err := injectSANMatcher(commonTLSContext, spiffeIDs...) + //if err != nil { + // return failoverTargets, fmt.Errorf("failed to inject SAN matcher rules for cluster %q: %v", sni, err) + //} + + //tlsContext := &envoy_tls_v3.UpstreamTlsContext{ + // CommonTlsContext: commonTLSContext, + // Sni: sni, + //} + //ti.TLSContext = tlsContext failoverTargets.targets = append(failoverTargets.targets, ti) } diff --git a/agent/xds/resources_test.go b/agent/xds/resources_test.go index f5a4acca38b09..b47edcbac3684 100644 --- a/agent/xds/resources_test.go +++ b/agent/xds/resources_test.go @@ -4,10 +4,6 @@ package xds import ( - "fmt" - "github.com/hashicorp/consul/agent/xds/proxystateconverter" - "github.com/hashicorp/consul/agent/xdsv2" - "google.golang.org/protobuf/proto" "path/filepath" "sort" "testing" @@ -50,7 +46,6 @@ type goldenTestCase struct { setup func(snap *proxycfg.ConfigSnapshot) overrideGoldenName string generatorSetup func(*ResourceGenerator) - alsoRunTestForV2 bool } func TestAllResourcesFromSnapshot(t *testing.T) { @@ -82,33 +77,6 @@ func TestAllResourcesFromSnapshot(t *testing.T) { tt.setup(snap) } - typeUrls := []string{ - xdscommon.ListenerType, - xdscommon.RouteType, - xdscommon.ClusterType, - xdscommon.EndpointType, - xdscommon.SecretType, - } - - resourceSortingFunc := func(items []proto.Message, typeURL string) func(i, j int) bool { - return func(i, j int) bool { - switch typeURL { - case xdscommon.ListenerType: - return items[i].(*envoy_listener_v3.Listener).Name < items[j].(*envoy_listener_v3.Listener).Name - case xdscommon.RouteType: - return items[i].(*envoy_route_v3.RouteConfiguration).Name < items[j].(*envoy_route_v3.RouteConfiguration).Name - case xdscommon.ClusterType: - return items[i].(*envoy_cluster_v3.Cluster).Name < items[j].(*envoy_cluster_v3.Cluster).Name - case xdscommon.EndpointType: - return items[i].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName < items[j].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName - case xdscommon.SecretType: - return items[i].(*envoy_tls_v3.Secret).Name < items[j].(*envoy_tls_v3.Secret).Name - default: - panic("not possible") - } - } - } - // Need server just for logger dependency g := NewResourceGenerator(testutil.Logger(t), nil, false) g.ProxyFeatures = sf @@ -119,15 +87,37 @@ func TestAllResourcesFromSnapshot(t *testing.T) { resources, err := g.AllResourcesFromSnapshot(snap) require.NoError(t, err) + typeUrls := []string{ + xdscommon.ListenerType, + xdscommon.RouteType, + xdscommon.ClusterType, + xdscommon.EndpointType, + xdscommon.SecretType, + } require.Len(t, resources, len(typeUrls)) for _, typeUrl := range typeUrls { prettyName := testTypeUrlToPrettyName[typeUrl] - t.Run(fmt.Sprintf("xdsv1-%s", prettyName), func(t *testing.T) { + t.Run(prettyName, func(t *testing.T) { items, ok := resources[typeUrl] require.True(t, ok) - sort.Slice(items, resourceSortingFunc(items, typeUrl)) + sort.Slice(items, func(i, j int) bool { + switch typeUrl { + case xdscommon.ListenerType: + return items[i].(*envoy_listener_v3.Listener).Name < items[j].(*envoy_listener_v3.Listener).Name + case xdscommon.RouteType: + return items[i].(*envoy_route_v3.RouteConfiguration).Name < items[j].(*envoy_route_v3.RouteConfiguration).Name + case xdscommon.ClusterType: + return items[i].(*envoy_cluster_v3.Cluster).Name < items[j].(*envoy_cluster_v3.Cluster).Name + case xdscommon.EndpointType: + return items[i].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName < items[j].(*envoy_endpoint_v3.ClusterLoadAssignment).ClusterName + case xdscommon.SecretType: + return items[i].(*envoy_tls_v3.Secret).Name < items[j].(*envoy_tls_v3.Secret).Name + default: + panic("not possible") + } + }) r, err := response.CreateResponse(typeUrl, "00000001", "00000001", items) require.NoError(t, err) @@ -143,43 +133,6 @@ func TestAllResourcesFromSnapshot(t *testing.T) { require.JSONEq(t, expectedJSON, gotJSON) }) } - - if tt.alsoRunTestForV2 { - generator := xdsv2.NewResourceGenerator(testutil.Logger(t)) - - converter := proxystateconverter.NewConverter(testutil.Logger(t), &mockCfgFetcher{addressLan: "10.10.10.10"}) - proxyState, err := converter.ProxyStateFromSnapshot(snap) - require.NoError(t, err) - - v2Resources, err := generator.AllResourcesFromIR(proxyState) - require.NoError(t, err) - require.Len(t, v2Resources, len(typeUrls)-1) // secrets are not currently implemented in V2. - for _, typeUrl := range typeUrls { - prettyName := testTypeUrlToPrettyName[typeUrl] - t.Run(fmt.Sprintf("xdsv2-%s", prettyName), func(t *testing.T) { - if typeUrl == xdscommon.SecretType { - t.Skip("skipping. secrets are not yet implemented in xdsv2") - } - items, ok := v2Resources[typeUrl] - require.True(t, ok) - - sort.Slice(items, resourceSortingFunc(items, typeUrl)) - - r, err := response.CreateResponse(typeUrl, "00000001", "00000001", items) - require.NoError(t, err) - - gotJSON := protoToJSON(t, r) - - gName := tt.name - if tt.overrideGoldenName != "" { - gName = tt.overrideGoldenName - } - - expectedJSON := goldenEnvoy(t, filepath.Join(prettyName, gName), envoyVersion, latestEnvoyVersion, gotJSON) - require.JSONEq(t, expectedJSON, gotJSON) - }) - } - } } tests := []testcase{ @@ -188,28 +141,6 @@ func TestAllResourcesFromSnapshot(t *testing.T) { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshot(t, nil, nil) }, - alsoRunTestForV2: true, - }, - { - name: "connect-proxy-with-chain", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", false, nil, nil) - }, - alsoRunTestForV2: true, - }, - { - name: "connect-proxy-with-chain-external-sni", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", false, nil, nil) - }, - alsoRunTestForV2: true, - }, - { - name: "connect-proxy-with-chain-and-failover", - create: func(t testinf.T) *proxycfg.ConfigSnapshot { - return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover", false, nil, nil) - }, - alsoRunTestForV2: true, }, { name: "connect-proxy-exported-to-peers", @@ -225,49 +156,36 @@ func TestAllResourcesFromSnapshot(t *testing.T) { }, }) }, - alsoRunTestForV2: true, }, { name: "transparent-proxy", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotTransparentProxy(t) }, - alsoRunTestForV2: true, }, { name: "connect-proxy-with-peered-upstreams", create: proxycfg.TestConfigSnapshotPeering, - // TODO(proxystate): peering will come at a later date. - alsoRunTestForV2: false, }, { name: "connect-proxy-with-peered-upstreams-escape-overrides", create: proxycfg.TestConfigSnapshotPeeringWithEscapeOverrides, - // TODO(proxystate): peering will come at a later date. - alsoRunTestForV2: false, }, { name: "connect-proxy-with-peered-upstreams-http2", create: proxycfg.TestConfigSnapshotPeeringWithHTTP2, - // TODO(proxystate): peering will come at a later date. - alsoRunTestForV2: false, }, { name: "transparent-proxy-with-peered-upstreams", create: proxycfg.TestConfigSnapshotPeeringTProxy, - // TODO(proxystate): peering will come at a later date. - alsoRunTestForV2: false, }, { name: "local-mesh-gateway-with-peered-upstreams", create: proxycfg.TestConfigSnapshotPeeringLocalMeshGateway, - // TODO(proxystate): mesh gateways and peering will come at a later date. - alsoRunTestForV2: false, }, { - name: "telemetry-collector", - create: proxycfg.TestConfigSnapshotTelemetryCollector, - alsoRunTestForV2: false, + name: "telemetry-collector", + create: proxycfg.TestConfigSnapshotTelemetryCollector, }, } tests = append(tests, getConnectProxyTransparentProxyGoldenTestCases()...) @@ -295,24 +213,18 @@ func getConnectProxyTransparentProxyGoldenTestCases() []goldenTestCase { { name: "transparent-proxy-destination", create: proxycfg.TestConfigSnapshotTransparentProxyDestination, - // TODO(proxystate): currently failing. should work. possible issue in converter. - alsoRunTestForV2: false, }, { name: "transparent-proxy-destination-http", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotTransparentProxyDestinationHTTP(t, nil) }, - // TODO(proxystate): currently failing. should work. possible issue in converter. - alsoRunTestForV2: false, }, { name: "transparent-proxy-terminating-gateway-destinations-only", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotTerminatingGatewayDestinations(t, true, nil) }, - // TODO(proxystate): terminating gateways will come at a later date. - alsoRunTestForV2: false, }, } } @@ -324,32 +236,24 @@ func getMeshGatewayPeeringGoldenTestCases() []goldenTestCase { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotPeeredMeshGateway(t, "default-services-tcp", nil, nil) }, - // TODO(proxystate): mesh gateways will come at a later date. - alsoRunTestForV2: false, }, { name: "mesh-gateway-with-exported-peered-services-http", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotPeeredMeshGateway(t, "default-services-http", nil, nil) }, - // TODO(proxystate): mesh gateways will come at a later date. - alsoRunTestForV2: false, }, { name: "mesh-gateway-with-exported-peered-services-http-with-router", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotPeeredMeshGateway(t, "chain-and-l7-stuff", nil, nil) }, - // TODO(proxystate): mesh gateways will come at a later date. - alsoRunTestForV2: false, }, { name: "mesh-gateway-peering-control-plane", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotPeeredMeshGateway(t, "control-plane", nil, nil) }, - // TODO(proxystate): mesh gateways will come at a later date. - alsoRunTestForV2: false, }, { name: "mesh-gateway-with-imported-peered-services", @@ -360,16 +264,12 @@ func getMeshGatewayPeeringGoldenTestCases() []goldenTestCase { } }, nil) }, - // TODO(proxystate): mesh gateways will come at a later date. - alsoRunTestForV2: false, }, { name: "mesh-gateway-with-peer-through-mesh-gateway-enabled", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotPeeredMeshGateway(t, "peer-through-mesh-gateway", nil, nil) }, - // TODO(proxystate): mesh gateways will come at a later date. - alsoRunTestForV2: false, }, } } @@ -381,16 +281,12 @@ func getTrafficControlPeeringGoldenTestCases(enterprise bool) []goldenTestCase { create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "failover-to-cluster-peer", enterprise, nil, nil) }, - // TODO(proxystate): peering will come at a later date. - alsoRunTestForV2: false, }, { name: "connect-proxy-with-chain-and-redirect-to-cluster-peer", create: func(t testinf.T) *proxycfg.ConfigSnapshot { return proxycfg.TestConfigSnapshotDiscoveryChain(t, "redirect-to-cluster-peer", enterprise, nil, nil) }, - // TODO(proxystate): peering will come at a later date. - alsoRunTestForV2: false, }, } @@ -557,8 +453,6 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { Certificate: gatewayTestCertificate, }}, nil) }, - // TODO(proxystate): api gateways will come at a later date. - alsoRunTestForV2: false, }, { name: "api-gateway-with-multiple-inline-certificates", @@ -632,8 +526,6 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { }, }, nil) }, - // TODO(proxystate): api gateways will come at a later date. - alsoRunTestForV2: false, }, { name: "api-gateway-with-http-route", @@ -715,8 +607,6 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { }, }}) }, - // TODO(proxystate): api gateways will come at a later date. - alsoRunTestForV2: false, }, { name: "api-gateway-with-http-route-timeoutfilter-one-set", @@ -791,8 +681,6 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { }, }}) }, - // TODO(proxystate): api gateways will come at a later date. - alsoRunTestForV2: false, }, } } diff --git a/agent/xds/routes.go b/agent/xds/routes.go index d4e289e033785..99d72735b35d6 100644 --- a/agent/xds/routes.go +++ b/agent/xds/routes.go @@ -61,11 +61,6 @@ func (s *ResourceGenerator) routesForConnectProxy(cfgSnap *proxycfg.ConfigSnapsh continue } - if !structs.IsProtocolHTTPLike(chain.Protocol) { - // Routes can only be defined for HTTP services - continue - } - virtualHost, err := s.makeUpstreamRouteForDiscoveryChain(cfgSnap, uid, chain, []string{"*"}, false, perRouteFilterBuilder{}) if err != nil { return nil, err diff --git a/agent/xds/routes_test.go b/agent/xds/routes_test.go index 616331036118e..eda10f2234667 100644 --- a/agent/xds/routes_test.go +++ b/agent/xds/routes_test.go @@ -33,6 +33,20 @@ type routeTestCase struct { func makeRouteDiscoChainTests(enterprise bool) []routeTestCase { return []routeTestCase{ + { + name: "connect-proxy-with-chain", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "simple", enterprise, nil, nil) + }, + alsoRunTestForV2: true, + }, + { + name: "connect-proxy-with-chain-external-sni", + create: func(t testinf.T) *proxycfg.ConfigSnapshot { + return proxycfg.TestConfigSnapshotDiscoveryChain(t, "external-sni", enterprise, nil, nil) + }, + alsoRunTestForV2: true, + }, { name: "connect-proxy-splitter-overweight", create: func(t testinf.T) *proxycfg.ConfigSnapshot { diff --git a/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-failover.latest.golden b/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-failover.latest.golden index 8b919343d21a9..63ede4b9ebe1e 100644 --- a/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-failover.latest.golden +++ b/agent/xds/testdata/builtin_extension/routes/propertyoverride-patch-specific-upstream-service-failover.latest.golden @@ -1,5 +1,32 @@ { "nonce": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "mostSpecificHeaderMutationsWins": true, + "name": "db", + "validateClusters": true, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "db", + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "33s" + } + } + ] + } + ] + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "versionInfo": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/transparent-proxy-catalog-destinations-only.latest.golden b/agent/xds/testdata/endpoints/transparent-proxy-catalog-destinations-only.latest.golden deleted file mode 100644 index ebf0eb91d97e9..0000000000000 --- a/agent/xds/testdata/endpoints/transparent-proxy-catalog-destinations-only.latest.golden +++ /dev/null @@ -1,104 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "google.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "9.9.9.9", - "portValue": 9090 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "no-endpoints.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - {} - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/endpoints/transparent-proxy-dial-instances-directly.latest.golden b/agent/xds/testdata/endpoints/transparent-proxy-dial-instances-directly.latest.golden deleted file mode 100644 index 202693781ebd6..0000000000000 --- a/agent/xds/testdata/endpoints/transparent-proxy-dial-instances-directly.latest.golden +++ /dev/null @@ -1,131 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.2", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.1.1", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.20.1.2", - "portValue": 8080 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "kafka.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "9.9.9.9", - "portValue": 9092 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "mongo.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.10.10", - "portValue": 27017 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - }, - { - "endpoint": { - "address": { - "socketAddress": { - "address": "10.10.10.12", - "portValue": 27017 - } - } - }, - "healthStatus": "HEALTHY", - "loadBalancingWeight": 1 - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-chain-and-failover.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-chain-and-failover.latest.golden deleted file mode 100644 index 0254a224d513b..0000000000000 --- a/agent/xds/testdata/listeners/connect-proxy-with-chain-and-failover.latest.golden +++ /dev/null @@ -1,115 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9191 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" - } - } - ] - } - ], - "name": "db:127.0.0.1:9191", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.10.10.10", - "portValue": 8181 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" - } - } - ] - } - ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "0.0.0.0", - "portValue": 9999 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/listeners/connect-proxy-with-chain.latest.golden b/agent/xds/testdata/listeners/connect-proxy-with-chain.latest.golden deleted file mode 100644 index 0254a224d513b..0000000000000 --- a/agent/xds/testdata/listeners/connect-proxy-with-chain.latest.golden +++ /dev/null @@ -1,115 +0,0 @@ -{ - "nonce": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 9191 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.db.default.default.dc1" - } - } - ] - } - ], - "name": "db:127.0.0.1:9191", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "127.10.10.10", - "portValue": 8181 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "geo-cache.default.dc1.query.11111111-2222-3333-4444-555555555555.consul", - "statPrefix": "upstream.prepared_query_geo-cache" - } - } - ] - } - ], - "name": "prepared_query:geo-cache:127.10.10.10:8181", - "trafficDirection": "OUTBOUND" - }, - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "address": { - "socketAddress": { - "address": "0.0.0.0", - "portValue": 9999 - } - }, - "filterChains": [ - { - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "local_app", - "statPrefix": "public_listener" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICjDCCAjKgAwIBAgIIC5llxGV1gB8wCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowDjEMMAoG\nA1UEAxMDd2ViMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEADPv1RHVNRfa2VKR\nAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Favq5E0ivpNtv1QnFhxtPd7d5k4e+T7\nSkW1TaOCAXIwggFuMA4GA1UdDwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcD\nAgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIwADBoBgNVHQ4EYQRfN2Q6MDc6ODc6M2E6\nNDA6MTk6NDc6YzM6NWE6YzA6YmE6NjI6ZGY6YWY6NGI6ZDQ6MDU6MjU6NzY6M2Q6\nNWE6OGQ6MTY6OGQ6Njc6NWU6MmU6YTA6MzQ6N2Q6ZGM6ZmYwagYDVR0jBGMwYYBf\nZDE6MTE6MTE6YWM6MmE6YmE6OTc6YjI6M2Y6YWM6N2I6YmQ6ZGE6YmU6YjE6OGE6\nZmM6OWE6YmE6YjU6YmM6ODM6ZTc6NWU6NDE6NmY6ZjI6NzM6OTU6NTg6MGM6ZGIw\nWQYDVR0RBFIwUIZOc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9ucy9kZWZhdWx0L2RjL2RjMS9zdmMvd2ViMAoGCCqG\nSM49BAMCA0gAMEUCIGC3TTvvjj76KMrguVyFf4tjOqaSCRie3nmHMRNNRav7AiEA\npY0heYeK9A6iOLrzqxSerkXXQyj5e9bE4VgUnxgPU6g=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIMoTkpRggp3fqZzFKh82yS4LjtJI+XY+qX/7DefHFrtdoAoGCCqGSM49\nAwEHoUQDQgAEADPv1RHVNRfa2VKRAB16b6rZnEt7tuhaxCFpQXPj7M2omb0B9Fav\nq5E0ivpNtv1QnFhxtPd7d5k4e+T7SkW1TQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "trustedCa": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICXDCCAgKgAwIBAgIICpZq70Z9LyUwCgYIKoZIzj0EAwIwFDESMBAGA1UEAxMJ\nVGVzdCBDQSAyMB4XDTE5MDMyMjEzNTgyNloXDTI5MDMyMjEzNTgyNlowFDESMBAG\nA1UEAxMJVGVzdCBDQSAyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEIhywH1gx\nAsMwuF3ukAI5YL2jFxH6Usnma1HFSfVyxbXX1/uoZEYrj8yCAtdU2yoHETyd+Zx2\nThhRLP79pYegCaOCATwwggE4MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTAD\nAQH/MGgGA1UdDgRhBF9kMToxMToxMTphYzoyYTpiYTo5NzpiMjozZjphYzo3Yjpi\nZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1ZTo0MTo2ZjpmMjo3\nMzo5NTo1ODowYzpkYjBqBgNVHSMEYzBhgF9kMToxMToxMTphYzoyYTpiYTo5Nzpi\nMjozZjphYzo3YjpiZDpkYTpiZTpiMTo4YTpmYzo5YTpiYTpiNTpiYzo4MzplNzo1\nZTo0MTo2ZjpmMjo3Mzo5NTo1ODowYzpkYjA/BgNVHREEODA2hjRzcGlmZmU6Ly8x\nMTExMTExMS0yMjIyLTMzMzMtNDQ0NC01NTU1NTU1NTU1NTUuY29uc3VsMAoGCCqG\nSM49BAMCA0gAMEUCICOY0i246rQHJt8o8Oya0D5PLL1FnmsQmQqIGCi31RwnAiEA\noR5f6Ku+cig2Il8T8LJujOp2/2A72QcHZA57B13y+8o=\n-----END CERTIFICATE-----\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "name": "public_listener:0.0.0.0:9999", - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden index 8b919343d21a9..9a73db46e0d6e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover-to-cluster-peer.latest.golden @@ -1,5 +1,31 @@ { "nonce": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "validateClusters": true, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "db", + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "33s" + } + } + ] + } + ] + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "versionInfo": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover.latest.golden deleted file mode 100644 index 8b919343d21a9..0000000000000 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-and-failover.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden index 8b919343d21a9..b5da244e3e67f 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-and-redirect-to-cluster-peer.latest.golden @@ -1,5 +1,31 @@ { "nonce": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "validateClusters": true, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "db", + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "db.default.cluster-01.external.peer1.domain", + "timeout": "33s" + } + } + ] + } + ] + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "versionInfo": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain-external-sni.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain-external-sni.latest.golden index 8b919343d21a9..9a73db46e0d6e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain-external-sni.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain-external-sni.latest.golden @@ -1,5 +1,31 @@ { "nonce": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "validateClusters": true, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "db", + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "33s" + } + } + ] + } + ] + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "versionInfo": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/connect-proxy-with-chain.latest.golden b/agent/xds/testdata/routes/connect-proxy-with-chain.latest.golden index 8b919343d21a9..9a73db46e0d6e 100644 --- a/agent/xds/testdata/routes/connect-proxy-with-chain.latest.golden +++ b/agent/xds/testdata/routes/connect-proxy-with-chain.latest.golden @@ -1,5 +1,31 @@ { "nonce": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "db", + "validateClusters": true, + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "db", + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "db.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul", + "timeout": "33s" + } + } + ] + } + ] + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "versionInfo": "00000001" } \ No newline at end of file diff --git a/agent/xds/testdata/routes/transparent-proxy-catalog-destinations-only.latest.golden b/agent/xds/testdata/routes/transparent-proxy-catalog-destinations-only.latest.golden deleted file mode 100644 index 8b919343d21a9..0000000000000 --- a/agent/xds/testdata/routes/transparent-proxy-catalog-destinations-only.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/routes/transparent-proxy-dial-instances-directly.latest.golden b/agent/xds/testdata/routes/transparent-proxy-dial-instances-directly.latest.golden deleted file mode 100644 index 8b919343d21a9..0000000000000 --- a/agent/xds/testdata/routes/transparent-proxy-dial-instances-directly.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-chain-and-failover.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-chain-and-failover.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/connect-proxy-with-chain-and-failover.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-chain-external-sni.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-chain-external-sni.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/connect-proxy-with-chain-external-sni.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/connect-proxy-with-chain.latest.golden b/agent/xds/testdata/secrets/connect-proxy-with-chain.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/connect-proxy-with-chain.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/transparent-proxy-catalog-destinations-only.latest.golden b/agent/xds/testdata/secrets/transparent-proxy-catalog-destinations-only.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/transparent-proxy-catalog-destinations-only.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xds/testdata/secrets/transparent-proxy-dial-instances-directly.latest.golden b/agent/xds/testdata/secrets/transparent-proxy-dial-instances-directly.latest.golden deleted file mode 100644 index 82e45650658b4..0000000000000 --- a/agent/xds/testdata/secrets/transparent-proxy-dial-instances-directly.latest.golden +++ /dev/null @@ -1,5 +0,0 @@ -{ - "nonce": "00000001", - "typeUrl": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret", - "versionInfo": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/cluster_resources.go b/agent/xdsv2/cluster_resources.go index 6e33d64ecf6bd..d32eeed2ec62b 100644 --- a/agent/xdsv2/cluster_resources.go +++ b/agent/xdsv2/cluster_resources.go @@ -6,6 +6,7 @@ package xdsv2 import ( "errors" "fmt" + envoy_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_aggregate_cluster_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/clusters/aggregate/v3" @@ -18,13 +19,43 @@ import ( "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" ) -func (pr *ProxyResources) makeClusters(name string) (map[string]proto.Message, error) { - envoyClusters := make(map[string]proto.Message) +func (pr *ProxyResources) doesEnvoyClusterAlreadyExist(name string) bool { + // TODO(proxystate): consider using a map instead of [] for this kind of lookup + for _, envoyCluster := range pr.envoyResources[xdscommon.ClusterType] { + if envoyCluster.(*envoy_cluster_v3.Cluster).Name == name { + return true + } + } + return false +} + +func (pr *ProxyResources) makeXDSClusters() ([]proto.Message, error) { + clusters := make([]proto.Message, 0) + + for clusterName := range pr.proxyState.Clusters { + protoCluster, err := pr.makeClusters(clusterName) + // TODO: aggregate errors for clusters and still return any properly formed clusters. + if err != nil { + return nil, err + } + clusters = append(clusters, protoCluster...) + } + + return clusters, nil +} + +func (pr *ProxyResources) makeClusters(name string) ([]proto.Message, error) { + clusters := make([]proto.Message, 0) proxyStateCluster, ok := pr.proxyState.Clusters[name] if !ok { return nil, fmt.Errorf("cluster %q not found", name) } + if pr.doesEnvoyClusterAlreadyExist(name) { + // don't error + return []proto.Message{}, nil + } + switch proxyStateCluster.Group.(type) { case *pbproxystate.Cluster_FailoverGroup: fg := proxyStateCluster.GetFailoverGroup() @@ -33,7 +64,7 @@ func (pr *ProxyResources) makeClusters(name string) (map[string]proto.Message, e return nil, err } for _, c := range clusters { - envoyClusters[c.Name] = c + clusters = append(clusters, c) } case *pbproxystate.Cluster_EndpointGroup: @@ -42,12 +73,12 @@ func (pr *ProxyResources) makeClusters(name string) (map[string]proto.Message, e if err != nil { return nil, err } - envoyClusters[cluster.Name] = cluster + clusters = append(clusters, cluster) default: return nil, errors.New("cluster group type should be Endpoint Group or Failover Group") } - return envoyClusters, nil + return clusters, nil } func (pr *ProxyResources) makeEnvoyCluster(name string, protocol pbproxystate.Protocol, eg *pbproxystate.EndpointGroup) (*envoy_cluster_v3.Cluster, error) { @@ -176,8 +207,8 @@ func (pr *ProxyResources) makeEnvoyPassthroughCluster(name string, protocol pbpr return cluster, nil } -func (pr *ProxyResources) makeEnvoyAggregateCluster(name string, protocol pbproxystate.Protocol, fg *pbproxystate.FailoverGroup) (map[string]*envoy_cluster_v3.Cluster, error) { - clusters := make(map[string]*envoy_cluster_v3.Cluster) +func (pr *ProxyResources) makeEnvoyAggregateCluster(name string, protocol pbproxystate.Protocol, fg *pbproxystate.FailoverGroup) ([]*envoy_cluster_v3.Cluster, error) { + var clusters []*envoy_cluster_v3.Cluster if fg != nil { var egNames []string for _, eg := range fg.EndpointGroups { @@ -186,7 +217,7 @@ func (pr *ProxyResources) makeEnvoyAggregateCluster(name string, protocol pbprox return nil, err } egNames = append(egNames, cluster.Name) - clusters[cluster.Name] = cluster + clusters = append(clusters, cluster) } aggregateClusterConfig, err := anypb.New(&envoy_aggregate_cluster_v3.ClusterConfig{ Clusters: egNames, @@ -214,7 +245,7 @@ func (pr *ProxyResources) makeEnvoyAggregateCluster(name string, protocol pbprox if err != nil { return nil, err } - clusters[c.Name] = c + clusters = append(clusters, c) } return clusters, nil } @@ -345,19 +376,9 @@ func addEnvoyLBToCluster(dynamicConfig *pbproxystate.DynamicEndpointGroupConfig, return nil } +// TODO(proxystate): In a future PR this will create clusters and add it to ProxyResources.proxyState +// Currently, we do not traverse the listener -> endpoint paths and instead just generate each resource by iterating +// through its top level map. In the future we want to traverse these paths to ensure each listener has a cluster, etc. func (pr *ProxyResources) makeEnvoyClusterFromL4Destination(l4 *pbproxystate.L4Destination) error { - switch l4.Destination.(type) { - case *pbproxystate.L4Destination_Cluster: - pr.addEnvoyClustersAndEndpointsToEnvoyResources(l4.GetCluster().GetName()) - - case *pbproxystate.L4Destination_WeightedClusters: - psWeightedClusters := l4.GetWeightedClusters() - for _, psCluster := range psWeightedClusters.GetClusters() { - pr.addEnvoyClustersAndEndpointsToEnvoyResources(psCluster.Name) - } - default: - return errors.New("cluster group type should be Endpoint Group or Failover Group") - } - return nil } diff --git a/agent/xdsv2/endpoint_resources.go b/agent/xdsv2/endpoint_resources.go index ce81d5cad0f60..fa3d39d8779fe 100644 --- a/agent/xdsv2/endpoint_resources.go +++ b/agent/xdsv2/endpoint_resources.go @@ -7,7 +7,9 @@ import ( envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" "github.com/hashicorp/consul/agent/xds/response" + "github.com/hashicorp/consul/envoyextensions/xdscommon" "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" + "google.golang.org/protobuf/proto" ) func makeEnvoyLbEndpoint(endpoint *pbproxystate.Endpoint) *envoy_endpoint_v3.LbEndpoint { @@ -44,3 +46,16 @@ func makeEnvoyClusterLoadAssignment(clusterName string, endpoints []*pbproxystat Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{localityLbEndpoints}, } } + +func (pr *ProxyResources) makeXDSEndpoints() ([]proto.Message, error) { + endpoints := make([]proto.Message, 0) + + for clusterName, eps := range pr.proxyState.GetEndpoints() { + if clusterName != xdscommon.LocalAppClusterName { + protoEndpoint := makeEnvoyClusterLoadAssignment(clusterName, eps.Endpoints) + endpoints = append(endpoints, protoEndpoint) + } + } + + return endpoints, nil +} diff --git a/agent/xdsv2/listener_resources.go b/agent/xdsv2/listener_resources.go index a7f3976ed5704..1ccfb42a6d5e1 100644 --- a/agent/xdsv2/listener_resources.go +++ b/agent/xdsv2/listener_resources.go @@ -42,16 +42,18 @@ const ( envoyHttpConnectionManagerFilterName = "envoy.filters.network.http_connection_manager" ) -func (pr *ProxyResources) makeEnvoyResourceGraphsStartingFromListeners() error { +func (pr *ProxyResources) makeXDSListeners() ([]proto.Message, error) { + listeners := make([]proto.Message, 0) + for _, l := range pr.proxyState.Listeners { protoListener, err := pr.makeListener(l) // TODO: aggregate errors for listeners and still return any properly formed listeners. if err != nil { - return err + return nil, err } - pr.envoyResources[xdscommon.ListenerType][protoListener.Name] = protoListener + listeners = append(listeners, protoListener) } - return nil + return listeners, nil } func (pr *ProxyResources) makeListener(listener *pbproxystate.Listener) (*envoy_listener_v3.Listener, error) { @@ -307,7 +309,7 @@ func (pr *ProxyResources) makeEnvoyResourcesForL4Destination(l4 *pbproxystate.Ro if err != nil { return nil, err } - envoyFilters, err := pr.makeL4Filters(l4.L4) + envoyFilters, err := makeL4Filters(l4.L4) return envoyFilters, err } @@ -332,7 +334,7 @@ func getAlpnProtocols(protocol pbproxystate.L7Protocol) []string { return alpnProtocols } -func (pr *ProxyResources) makeL4Filters(l4 *pbproxystate.L4Destination) ([]*envoy_listener_v3.Filter, error) { +func makeL4Filters(l4 *pbproxystate.L4Destination) ([]*envoy_listener_v3.Filter, error) { var envoyFilters []*envoy_listener_v3.Filter if l4 != nil { rbacFilters, err := MakeRBACNetworkFilters(l4.TrafficPermissions) @@ -440,7 +442,7 @@ func (pr *ProxyResources) makeL7Filters(l7 *pbproxystate.L7Destination) ([]*envo } } else { // Add Envoy route under the route resource since it's not inlined. - pr.envoyResources[xdscommon.RouteType][routeConfig.Name] = routeConfig + pr.envoyResources[xdscommon.RouteType] = append(pr.envoyResources[xdscommon.RouteType], routeConfig) httpConnMgr.RouteSpecifier = &envoy_http_v3.HttpConnectionManager_Rds{ Rds: &envoy_http_v3.Rds{ diff --git a/agent/xdsv2/resources.go b/agent/xdsv2/resources.go index 1c3251930cebb..fa5f7179e6a5d 100644 --- a/agent/xdsv2/resources.go +++ b/agent/xdsv2/resources.go @@ -20,7 +20,6 @@ type ResourceGenerator struct { ProxyFeatures xdscommon.SupportedProxyFeatures } -// NewResourceGenerator will create a new ResourceGenerator. func NewResourceGenerator( logger hclog.Logger, ) *ResourceGenerator { @@ -29,63 +28,48 @@ func NewResourceGenerator( } } -// ProxyResources is the main state used to convert proxyState resources to Envoy resources. type ProxyResources struct { - // proxyState is the final proxyState computed by Consul controllers. - proxyState *proxytracker.ProxyState - // envoyResources is a map of each resource type (listener, endpoint, route, cluster, etc.) - // with a corresponding map of k/v pairs of resource name to envoy proto message. - // map[string]map[string]proto.Message is used over map[string][]proto.Message because - // AllResourcesFromIR() will create envoy resource by walking the object graph from listener - // to endpoint. In the process, the same resource might be referenced more than once, - // so the map is used to prevent duplicate resources being created and also will use - // an O(1) lookup to see if it exists (it actually will set the map key rather than - // checks everywhere) where as each lookup would be O(n) with a []proto structure. - envoyResources map[string]map[string]proto.Message + proxyState *proxytracker.ProxyState + envoyResources map[string][]proto.Message } func (g *ResourceGenerator) AllResourcesFromIR(proxyState *proxytracker.ProxyState) (map[string][]proto.Message, error) { pr := &ProxyResources{ proxyState: proxyState, - envoyResources: make(map[string]map[string]proto.Message), + envoyResources: make(map[string][]proto.Message), } - pr.envoyResources[xdscommon.ListenerType] = make(map[string]proto.Message) - pr.envoyResources[xdscommon.RouteType] = make(map[string]proto.Message) - pr.envoyResources[xdscommon.ClusterType] = make(map[string]proto.Message) - pr.envoyResources[xdscommon.EndpointType] = make(map[string]proto.Message) - - err := pr.makeEnvoyResourceGraphsStartingFromListeners() + err := pr.generateXDSResources() if err != nil { return nil, fmt.Errorf("failed to generate xDS resources for ProxyState: %v", err) } + return pr.envoyResources, nil +} - // Now account for Clusters that did not have a destination. - for name := range proxyState.Clusters { - if _, ok := pr.envoyResources[xdscommon.ClusterType][name]; !ok { - pr.addEnvoyClustersAndEndpointsToEnvoyResources(name) - } +func (pr *ProxyResources) generateXDSResources() error { + listeners, err := pr.makeXDSListeners() + if err != nil { + return err } - envoyResources := convertResourceMapsToResourceArrays(pr.envoyResources) - return envoyResources, nil -} + pr.envoyResources[xdscommon.ListenerType] = listeners -// convertResourceMapsToResourceArrays will convert map[string]map[string]proto.Message, which is used to -// prevent duplicate resource being created, to map[string][]proto.Message which is used by Delta server. -func convertResourceMapsToResourceArrays(resourceMap map[string]map[string]proto.Message) map[string][]proto.Message { - resources := make(map[string][]proto.Message) - resources[xdscommon.ListenerType] = make([]proto.Message, 0) - resources[xdscommon.RouteType] = make([]proto.Message, 0) - resources[xdscommon.ClusterType] = make([]proto.Message, 0) - resources[xdscommon.EndpointType] = make([]proto.Message, 0) + clusters, err := pr.makeXDSClusters() + if err != nil { + return err + } + pr.envoyResources[xdscommon.ClusterType] = clusters - // This conversion incurs processing cost which is done once in the generating envoy resources. - // This tradeoff is preferable to doing array scan every time an envoy resource needs to be - // to pr.envoyResource to see if it already exists. - for resourceTypeName, resourceMap := range resourceMap { - for _, resource := range resourceMap { - resources[resourceTypeName] = append(resources[resourceTypeName], resource) - } + endpoints, err := pr.makeXDSEndpoints() + if err != nil { + return err } - return resources + pr.envoyResources[xdscommon.EndpointType] = endpoints + + routes, err := pr.makeXDSRoutes() + if err != nil { + return err + } + pr.envoyResources[xdscommon.RouteType] = routes + + return nil } diff --git a/agent/xdsv2/resources_test.go b/agent/xdsv2/resources_test.go index 1210124494e44..c1afbda705be8 100644 --- a/agent/xdsv2/resources_test.go +++ b/agent/xdsv2/resources_test.go @@ -54,16 +54,17 @@ func TestAllResourcesFromIR_XDSGoldenFileInputs(t *testing.T) { "destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy", //sources - please add in alphabetical order - "source/l7-expose-paths", - "source/local-and-inbound-connections", - "source/multiple-workload-addresses-with-specific-ports", - "source/multiple-workload-addresses-without-ports", - "source/multiport-l4-multiple-workload-addresses-with-specific-ports", - "source/multiport-l4-multiple-workload-addresses-without-ports", - "source/multiport-l4-workload-with-only-mesh-port", - "source/multiport-l7-multiple-workload-addresses-with-specific-ports", - "source/multiport-l7-multiple-workload-addresses-without-ports", - "source/single-workload-address-without-ports", + //"source/l4-multiple-workload-addresses-with-specific-ports", + //"source/l4-multiple-workload-addresses-without-ports", + //"source/l4-single-workload-address-without-ports", + //"source/l7-expose-paths", + //"source/local-and-inbound-connections", + //"source/multiport-l4-multiple-workload-addresses-with-specific-ports", + //"source/multiport-l4-multiple-workload-addresses-without-ports", + //"source/multiport-l4-workload-with-only-mesh-port", + //"source/multiport-l7-multiple-workload-addresses-with-specific-ports", + //"source/multiport-l7-multiple-workload-addresses-without-ports", + //"source/multiport-l7-multiple-workload-addresses-without-ports", } for _, name := range cases { diff --git a/agent/xdsv2/route_resources.go b/agent/xdsv2/route_resources.go index d2306fd43638d..af06c174484f8 100644 --- a/agent/xdsv2/route_resources.go +++ b/agent/xdsv2/route_resources.go @@ -16,8 +16,21 @@ import ( "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1/pbproxystate" envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + "google.golang.org/protobuf/proto" ) +func (pr *ProxyResources) makeXDSRoutes() ([]proto.Message, error) { + routes := make([]proto.Message, 0) + + for name, r := range pr.proxyState.Routes { + protoRoute := pr.makeEnvoyRouteConfigFromProxystateRoute(name, r) + // TODO: aggregate errors for routes and still return any properly formed routes. + routes = append(routes, protoRoute) + } + + return routes, nil +} + func (pr *ProxyResources) makeEnvoyRoute(name string) (*envoy_route_v3.RouteConfiguration, error) { var route *envoy_route_v3.RouteConfiguration // TODO(proxystate): This will make routes in the future. This function should distinguish between static routes @@ -234,20 +247,6 @@ func makeEnvoyQueryParamFromProxystateQueryMatch(psMatch *pbproxystate.QueryPara return envoyQueryParamMatcher } -func (pr *ProxyResources) addEnvoyClustersAndEndpointsToEnvoyResources(clusterName string) { - clusters, _ := pr.makeClusters(clusterName) - for name, cluster := range clusters { - pr.envoyResources[xdscommon.ClusterType][name] = cluster - - if name != xdscommon.LocalAppClusterName { - if endpointList, ok := pr.proxyState.Endpoints[name]; ok { - protoEndpoint := makeEnvoyClusterLoadAssignment(name, endpointList.Endpoints) - pr.envoyResources[xdscommon.EndpointType][name] = protoEndpoint - } - } - } -} - // TODO (dans): Will this always be envoy_route_v3.Route_Route? // Definitely for connect proxies this is the only option. func (pr *ProxyResources) makeEnvoyRouteActionFromProxystateRouteDestination(psRouteDestination *pbproxystate.RouteDestination) *envoy_route_v3.Route_Route { @@ -261,15 +260,16 @@ func (pr *ProxyResources) makeEnvoyRouteActionFromProxystateRouteDestination(psR envoyRouteRoute.Route.ClusterSpecifier = &envoy_route_v3.RouteAction_Cluster{ Cluster: psCluster.GetName(), } - pr.addEnvoyClustersAndEndpointsToEnvoyResources(psCluster.Name) + clusters, _ := pr.makeClusters(psCluster.Name) + pr.envoyResources[xdscommon.ClusterType] = append(pr.envoyResources[xdscommon.ClusterType], clusters...) case *pbproxystate.RouteDestination_WeightedClusters: psWeightedClusters := psRouteDestination.GetWeightedClusters() envoyClusters := make([]*envoy_route_v3.WeightedCluster_ClusterWeight, 0, len(psWeightedClusters.GetClusters())) totalWeight := 0 for _, psCluster := range psWeightedClusters.GetClusters() { - pr.addEnvoyClustersAndEndpointsToEnvoyResources(psCluster.Name) - + clusters, _ := pr.makeClusters(psCluster.Name) + pr.envoyResources[xdscommon.ClusterType] = append(pr.envoyResources[xdscommon.ClusterType], clusters...) totalWeight += int(psCluster.Weight.GetValue()) envoyClusters = append(envoyClusters, makeEnvoyClusterWeightFromProxystateWeightedCluster(psCluster)) } @@ -318,7 +318,10 @@ func (pr *ProxyResources) makeEnvoyRouteActionFromProxystateRouteDestination(psR } func makeEnvoyClusterWeightFromProxystateWeightedCluster(cluster *pbproxystate.L7WeightedDestinationCluster) *envoy_route_v3.WeightedCluster_ClusterWeight { - envoyClusterWeight := makeEnvoyClusterWeightFromNameAndWeight(cluster.GetName(), cluster.GetWeight()) + envoyClusterWeight := &envoy_route_v3.WeightedCluster_ClusterWeight{ + Name: cluster.GetName(), + Weight: cluster.GetWeight(), + } for _, hm := range cluster.GetHeaderMutations() { injectEnvoyClusterWeightWithProxystateHeaderMutation(envoyClusterWeight, hm) @@ -327,15 +330,6 @@ func makeEnvoyClusterWeightFromProxystateWeightedCluster(cluster *pbproxystate.L return envoyClusterWeight } -func makeEnvoyClusterWeightFromNameAndWeight(name string, weight *wrapperspb.UInt32Value) *envoy_route_v3.WeightedCluster_ClusterWeight { - envoyClusterWeight := &envoy_route_v3.WeightedCluster_ClusterWeight{ - Name: name, - Weight: weight, - } - - return envoyClusterWeight -} - func injectEnvoyClusterWeightWithProxystateHeaderMutation(envoyClusterWeight *envoy_route_v3.WeightedCluster_ClusterWeight, mutation *pbproxystate.HeaderMutation) { mutation.GetAction() switch mutation.GetAction().(type) { diff --git a/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden index b87031ba81b1b..280f42b8581f5 100644 --- a/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden +++ b/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden @@ -1,270 +1,157 @@ { - "versionInfo": "00000001", - "resources": [ + "versionInfo": "00000001", + "resources": [ { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "failover-target~0~http.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "http.api-2.default.dc1.internal.foo.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "connectTimeout": "55s", - "commonLbConfig": { - "healthyPanicThreshold": {} + "connectTimeout": "5s", + "commonLbConfig": { + "healthyPanicThreshold": {} }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" + "validationContext": { + "trustedCa": { + "inlineString": "some-root\nsome-other-root\n" }, - "matchSubjectAltNames": [ + "matchSubjectAltNames": [ { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" } ] }, - "alpnProtocols": [ + "alpnProtocols": [ "consul~http" ] }, - "sni": "api-1.default.dc1.internal.foo.consul" + "sni": "api-2.default.dc1.internal.foo.consul" } } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "failover-target~1~http.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/backup1-identity" - } - ] - }, - "alpnProtocols": [ - "consul~http" - ] - }, - "sni": "backup-1.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "http.api-1.default.dc1.internal.foo.consul", - "altStatName": "http.api-1.default.dc1.internal.foo.consul", - "clusterType": { - "name": "envoy.clusters.aggregate", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig", - "clusters": [ - "failover-target~0~http.api-1.default.dc1.internal.foo.consul", - "failover-target~1~http.api-1.default.dc1.internal.foo.consul" - ] - } - }, - "connectTimeout": "55s", - "lbPolicy": "CLUSTER_PROVIDED" - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "http.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" - } - }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - }, - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" - } - ] - }, - "alpnProtocols": [ - "consul~http" - ] - }, - "sni": "api-2.default.dc1.internal.foo.consul" - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "null_route_cluster", - "type": "STATIC", - "connectTimeout": "10s" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "null_route_cluster", + "type": "STATIC", + "connectTimeout": "10s" }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} + "connectTimeout": "5s", + "commonLbConfig": { + "healthyPanicThreshold": {} }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" + "validationContext": { + "trustedCa": { + "inlineString": "some-root\nsome-other-root\n" }, - "matchSubjectAltNames": [ + "matchSubjectAltNames": [ { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" } ] }, - "alpnProtocols": [ + "alpnProtocols": [ "consul~tcp" ] }, - "sni": "api-1.default.dc1.internal.foo.consul" + "sni": "api-1.default.dc1.internal.foo.consul" } } }, { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "tcp.api-2.default.dc1.internal.foo.consul", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": {}, - "resourceApiVersion": "V3" + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "type": "EDS", + "edsClusterConfig": { + "edsConfig": { + "ads": {}, + "resourceApiVersion": "V3" } }, - "connectTimeout": "5s", - "commonLbConfig": { - "healthyPanicThreshold": {} + "connectTimeout": "5s", + "commonLbConfig": { + "healthyPanicThreshold": {} }, - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" } } ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" + "validationContext": { + "trustedCa": { + "inlineString": "some-root\nsome-other-root\n" }, - "matchSubjectAltNames": [ + "matchSubjectAltNames": [ { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" } ] }, - "alpnProtocols": [ + "alpnProtocols": [ "consul~tcp" ] }, - "sni": "api-2.default.dc1.internal.foo.consul" + "sni": "api-2.default.dc1.internal.foo.consul" } } } ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 0000000000000..ce9870c06cd9d --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,31 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:port1", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:port1", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 0000000000000..ce9870c06cd9d --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,31 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:port1", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:port1", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/l4-single-workload-address-without-ports.golden b/agent/xdsv2/testdata/clusters/source/l4-single-workload-address-without-ports.golden new file mode 100644 index 0000000000000..ce9870c06cd9d --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/l4-single-workload-address-without-ports.golden @@ -0,0 +1,31 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:port1", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:port1", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 0d7d009aa1027..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,119 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:grpc", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:grpc", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8083 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:http", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:http", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8081 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:http2", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:http2", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8082 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:tcp", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:tcp", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 0d7d009aa1027..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,119 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:grpc", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:grpc", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8083 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:http", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:http", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8081 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:http2", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:http2", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8082 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:tcp", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:tcp", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/source/single-workload-address-without-ports.golden b/agent/xdsv2/testdata/clusters/source/single-workload-address-without-ports.golden deleted file mode 100644 index 0d7d009aa1027..0000000000000 --- a/agent/xdsv2/testdata/clusters/source/single-workload-address-without-ports.golden +++ /dev/null @@ -1,119 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:grpc", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:grpc", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8083 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:http", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:http", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8081 - } - } - } - } - ] - } - ] - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:http2", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:http2", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8082 - } - } - } - } - ] - } - ] - }, - "typedExtensionProtocolOptions": { - "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { - "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", - "explicitHttpConfig": { - "http2ProtocolOptions": {} - } - } - } - }, - { - "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "name": "local_app:tcp", - "type": "STATIC", - "loadAssignment": { - "clusterName": "local_app:tcp", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 0000000000000..b0c31e6e79c77 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,27 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:port1", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 0000000000000..b0c31e6e79c77 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,27 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:port1", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/l4-single-workload-address-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/l4-single-workload-address-without-ports.golden new file mode 100644 index 0000000000000..b0c31e6e79c77 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/l4-single-workload-address-without-ports.golden @@ -0,0 +1,27 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:port1", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 5fc63eef95996..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,87 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:grpc", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8083 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:http", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8081 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:http2", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8082 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:tcp", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 5fc63eef95996..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,87 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:grpc", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8083 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:http", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8081 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:http2", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8082 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:tcp", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/source/single-workload-address-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/single-workload-address-without-ports.golden deleted file mode 100644 index 5fc63eef95996..0000000000000 --- a/agent/xdsv2/testdata/endpoints/source/single-workload-address-without-ports.golden +++ /dev/null @@ -1,87 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:grpc", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8083 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:http", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8081 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:http2", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8082 - } - } - } - } - ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "clusterName": "local_app:tcp", - "endpoints": [ - { - "lbEndpoints": [ - { - "endpoint": { - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 8080 - } - } - } - } - ] - } - ] - } - ], - "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden index eae168bf8aa04..23dd5e4c6475c 100644 --- a/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden +++ b/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden @@ -17,7 +17,7 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.http.api-1.default.default.dc1", + "statPrefix": "upstream.", "rds": { "configSource": { "ads": {}, diff --git a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden index b0477d8310e14..9cd146e6ef0d5 100644 --- a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden @@ -47,7 +47,7 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.http.api-app.default.default.dc1", + "statPrefix": "upstream.", "rds": { "configSource": { "ads": {}, @@ -140,7 +140,7 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.http.api-app2.default.default.dc1", + "statPrefix": "upstream.", "rds": { "configSource": { "ads": {}, diff --git a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden index 180213b6523c0..71dec1b4db466 100644 --- a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden @@ -47,7 +47,7 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.http.api-app.default.default.dc1", + "statPrefix": "upstream.", "rds": { "configSource": { "ads": {}, diff --git a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden index 180213b6523c0..71dec1b4db466 100644 --- a/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -47,7 +47,7 @@ "name": "envoy.filters.network.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "upstream.http.api-app.default.default.dc1", + "statPrefix": "upstream.", "rds": { "configSource": { "ads": {}, diff --git a/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 0000000000000..644769d8423fc --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,100 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener", + "address": { + "socketAddress": { + "address": "10.0.0.2", + "portValue": 20000 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "applicationProtocols": [ + "consul~port1" + ] + }, + "filters": [ + { + "name": "envoy.filters.network.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", + "rules": { + "policies": { + "consul-intentions-layer4": { + "permissions": [ + { + "any": true + } + ], + "principals": [ + { + "authenticated": { + "principalName": { + "safeRegex": { + "googleRe2": {}, + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + } + } + ] + } + } + }, + "statPrefix": "connect_authz" + } + }, + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app:port1" + } + } + ], + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "some-root\nsome-other-root\n" + } + } + }, + "requireClientCertificate": true + } + } + } + ], + "listenerFilters": [ + { + "name": "envoy.filters.listener.tls_inspector", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" + } + } + ], + "trafficDirection": "INBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 0000000000000..82581d5762489 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,78 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener", + "address": { + "socketAddress": { + "address": "10.0.0.1", + "portValue": 20000 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "applicationProtocols": [ + "consul~port1" + ] + }, + "filters": [ + { + "name": "envoy.filters.network.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", + "rules": {}, + "statPrefix": "connect_authz" + } + }, + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app:port1" + } + } + ], + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "some-root\nsome-other-root\n" + } + } + }, + "requireClientCertificate": true + } + } + } + ], + "listenerFilters": [ + { + "name": "envoy.filters.listener.tls_inspector", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" + } + } + ], + "trafficDirection": "INBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/l4-single-workload-address-without-ports.golden b/agent/xdsv2/testdata/listeners/source/l4-single-workload-address-without-ports.golden new file mode 100644 index 0000000000000..82581d5762489 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/l4-single-workload-address-without-ports.golden @@ -0,0 +1,78 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener", + "address": { + "socketAddress": { + "address": "10.0.0.1", + "portValue": 20000 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "applicationProtocols": [ + "consul~port1" + ] + }, + "filters": [ + { + "name": "envoy.filters.network.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", + "rules": {}, + "statPrefix": "connect_authz" + } + }, + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "local_app:port1" + } + } + ], + "transportSocket": { + "name": "tls", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", + "commonTlsContext": { + "tlsParams": {}, + "tlsCertificates": [ + { + "certificateChain": { + "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" + }, + "privateKey": { + "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + } + } + ], + "validationContext": { + "trustedCa": { + "inlineString": "some-root\nsome-other-root\n" + } + } + }, + "requireClientCertificate": true + } + } + } + ], + "listenerFilters": [ + { + "name": "envoy.filters.listener.tls_inspector", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" + } + } + ], + "trafficDirection": "INBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index cb81777262f64..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,359 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "127.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~grpc" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:grpc", - "virtualHosts": [ - { - "name": "public_listener:grpc", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:grpc" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.grpc_stats", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig", - "statsForAllMethods": true - } - }, - { - "name": "envoy.filters.http.grpc_http1_bridge", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_http1_bridge.v3.Config" - } - }, - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~http" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:http", - "virtualHosts": [ - { - "name": "public_listener:http", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:http" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~http2" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:http2", - "virtualHosts": [ - { - "name": "public_listener:http2", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:http2" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~tcp" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:tcp" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 81f3bcca70ffe..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,359 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~grpc" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:grpc", - "virtualHosts": [ - { - "name": "public_listener:grpc", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:grpc" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.grpc_stats", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig", - "statsForAllMethods": true - } - }, - { - "name": "envoy.filters.http.grpc_http1_bridge", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_http1_bridge.v3.Config" - } - }, - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~http" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:http", - "virtualHosts": [ - { - "name": "public_listener:http", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:http" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~http2" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:http2", - "virtualHosts": [ - { - "name": "public_listener:http2", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:http2" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~tcp" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:tcp" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/source/single-workload-address-without-ports.golden b/agent/xdsv2/testdata/listeners/source/single-workload-address-without-ports.golden deleted file mode 100644 index 81f3bcca70ffe..0000000000000 --- a/agent/xdsv2/testdata/listeners/source/single-workload-address-without-ports.golden +++ /dev/null @@ -1,359 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", - "name": "public_listener", - "address": { - "socketAddress": { - "address": "10.0.0.1", - "portValue": 20000 - } - }, - "filterChains": [ - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~grpc" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:grpc", - "virtualHosts": [ - { - "name": "public_listener:grpc", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:grpc" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.grpc_stats", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_stats.v3.FilterConfig", - "statsForAllMethods": true - } - }, - { - "name": "envoy.filters.http.grpc_http1_bridge", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.grpc_http1_bridge.v3.Config" - } - }, - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~http" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:http", - "virtualHosts": [ - { - "name": "public_listener:http", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:http" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~http2" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.http_connection_manager", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", - "statPrefix": "public_listener", - "routeConfig": { - "name": "public_listener:http2", - "virtualHosts": [ - { - "name": "public_listener:http2", - "domains": [ - "*" - ], - "routes": [ - { - "match": { - "prefix": "/" - }, - "route": { - "cluster": "local_app:http2" - } - } - ] - } - ] - }, - "httpFilters": [ - { - "name": "envoy.filters.http.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} - } - }, - { - "name": "envoy.filters.http.router", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" - } - } - ], - "tracing": { - "randomSampling": {} - }, - "http2ProtocolOptions": {}, - "upgradeConfigs": [ - { - "upgradeType": "websocket" - } - ] - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - }, - "alpnProtocols": [ - "h2", - "http/1.1" - ] - }, - "requireClientCertificate": true - } - } - }, - { - "filterChainMatch": { - "applicationProtocols": [ - "consul~tcp" - ] - }, - "filters": [ - { - "name": "envoy.filters.network.rbac", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, - "statPrefix": "connect_authz" - } - }, - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "statPrefix": "public_listener", - "cluster": "local_app:tcp" - } - } - ], - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext", - "commonTlsContext": { - "tlsParams": {}, - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n" - }, - "privateKey": { - "inlineString": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - } - ], - "validationContext": { - "trustedCa": { - "inlineString": "some-root\nsome-other-root\n" - } - } - }, - "requireClientCertificate": true - } - } - } - ], - "listenerFilters": [ - { - "name": "envoy.filters.listener.tls_inspector", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" - } - } - ], - "trafficDirection": "INBOUND" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-with-specific-ports.golden similarity index 100% rename from agent/xdsv2/testdata/routes/source/multiple-workload-addresses-with-specific-ports.golden rename to agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-with-specific-ports.golden diff --git a/agent/xdsv2/testdata/routes/source/multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-without-ports.golden similarity index 100% rename from agent/xdsv2/testdata/routes/source/multiple-workload-addresses-without-ports.golden rename to agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-without-ports.golden diff --git a/agent/xdsv2/testdata/routes/source/single-workload-address-without-ports.golden b/agent/xdsv2/testdata/routes/source/l4-single-workload-address-without-ports.golden similarity index 100% rename from agent/xdsv2/testdata/routes/source/single-workload-address-without-ports.golden rename to agent/xdsv2/testdata/routes/source/l4-single-workload-address-without-ports.golden diff --git a/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden b/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden index 306f5220e7b9c..68b5239aec9ed 100644 --- a/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden +++ b/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden @@ -1,5 +1,53 @@ { "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "exposed_path_route_GetHealth1235", + "virtualHosts": [ + { + "name": "exposed_path_route_GetHealth1235", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "path": "GetHealth" + }, + "route": { + "cluster": "exposed_cluster_9091" + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "exposed_path_route_health1234", + "virtualHosts": [ + { + "name": "exposed_path_route_health1234", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "path": "/health" + }, + "route": { + "cluster": "exposed_cluster_9090" + } + } + ] + } + ], + "validateClusters": true + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden b/agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden index 306f5220e7b9c..97c96f44bb629 100644 --- a/agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden +++ b/agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden @@ -1,5 +1,77 @@ { "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "exposed_path_route_GetHealth1235", + "virtualHosts": [ + { + "name": "exposed_path_route_GetHealth1235", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "path": "GetHealth" + }, + "route": { + "cluster": "exposed_cluster_9091" + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "exposed_path_route_health1234", + "virtualHosts": [ + { + "name": "exposed_path_route_health1234", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "path": "/health" + }, + "route": { + "cluster": "exposed_cluster_9090" + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "public_listener:port3", + "virtualHosts": [ + { + "name": "public_listener:port3", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:port3", + "timeout": "9s" + } + } + ] + } + ], + "validateClusters": true + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden index 306f5220e7b9c..3b1a61403ba7d 100644 --- a/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden +++ b/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden @@ -1,5 +1,53 @@ { "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "public_listener:admin-port", + "virtualHosts": [ + { + "name": "public_listener:admin-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:admin-port" + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "public_listener:api-port", + "virtualHosts": [ + { + "name": "public_listener:api-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:api-port" + } + } + ] + } + ], + "validateClusters": true + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "nonce": "00000001" } \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden index 306f5220e7b9c..7f976890c64b0 100644 --- a/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden +++ b/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden @@ -1,5 +1,76 @@ { "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "public_listener:admin-port", + "virtualHosts": [ + { + "name": "public_listener:admin-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:admin-port" + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "public_listener:api-port", + "virtualHosts": [ + { + "name": "public_listener:api-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:api-port" + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "public_listener:grpc-port", + "virtualHosts": [ + { + "name": "public_listener:grpc-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:grpc-port" + } + } + ] + } + ], + "validateClusters": true + } + ], "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", "nonce": "00000001" } \ No newline at end of file diff --git a/go.mod b/go.mod index a443ce4336e5a..48c59e089101d 100644 --- a/go.mod +++ b/go.mod @@ -24,7 +24,6 @@ require ( github.com/aws/aws-sdk-go v1.44.289 github.com/coredns/coredns v1.10.1 github.com/coreos/go-oidc v2.1.0+incompatible - github.com/deckarep/golang-set/v2 v2.3.1 github.com/docker/go-connections v0.4.0 github.com/envoyproxy/go-control-plane v0.11.1 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e diff --git a/go.sum b/go.sum index 7ba17c40bc504..3598121de6f45 100644 --- a/go.sum +++ b/go.sum @@ -210,8 +210,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.3.1 h1:vjmkvJt/IV27WXPyYQpAh4bRyWJc5Y435D17XQ9QU5A= -github.com/deckarep/golang-set/v2 v2.3.1/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661 h1:lrWnAyy/F72MbxIxFUzKmcMCdt9Oi8RzpAxzTNQHD7o= github.com/denverdino/aliyungo v0.0.0-20170926055100-d3308649c661/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= diff --git a/internal/auth/internal/types/computed_traffic_permissions.go b/internal/auth/internal/types/computed_traffic_permissions.go index 800d2a8fb66f4..0a32e13d29267 100644 --- a/internal/auth/internal/types/computed_traffic_permissions.go +++ b/internal/auth/internal/types/computed_traffic_permissions.go @@ -12,8 +12,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedComputedTrafficPermissions = resource.DecodedResource[*pbauth.ComputedTrafficPermissions] - func RegisterComputedTrafficPermission(r resource.Registry) { r.Register(resource.Registration{ Type: pbauth.ComputedTrafficPermissionsType, @@ -28,12 +26,16 @@ func RegisterComputedTrafficPermission(r resource.Registry) { }) } -var ValidateComputedTrafficPermissions = resource.DecodeAndValidate(validateComputedTrafficPermissions) +func ValidateComputedTrafficPermissions(res *pbresource.Resource) error { + var ctp pbauth.ComputedTrafficPermissions + + if err := res.Data.UnmarshalTo(&ctp); err != nil { + return resource.NewErrDataParse(&ctp, err) + } -func validateComputedTrafficPermissions(res *DecodedComputedTrafficPermissions) error { var merr error - for i, permission := range res.Data.AllowPermissions { + for i, permission := range ctp.AllowPermissions { wrapErr := func(err error) error { return resource.ErrInvalidListElement{ Name: "allow_permissions", @@ -46,7 +48,7 @@ func validateComputedTrafficPermissions(res *DecodedComputedTrafficPermissions) } } - for i, permission := range res.Data.DenyPermissions { + for i, permission := range ctp.DenyPermissions { wrapErr := func(err error) error { return resource.ErrInvalidListElement{ Name: "deny_permissions", diff --git a/internal/auth/internal/types/traffic_permissions.go b/internal/auth/internal/types/traffic_permissions.go index acf2655371697..84a30a46e2f60 100644 --- a/internal/auth/internal/types/traffic_permissions.go +++ b/internal/auth/internal/types/traffic_permissions.go @@ -12,15 +12,13 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedTrafficPermissions = resource.DecodedResource[*pbauth.TrafficPermissions] - func RegisterTrafficPermissions(r resource.Registry) { r.Register(resource.Registration{ Type: pbauth.TrafficPermissionsType, Proto: &pbauth.TrafficPermissions{}, ACLs: &resource.ACLHooks{ - Read: resource.DecodeAndAuthorizeRead(aclReadHookTrafficPermissions), - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookTrafficPermissions), + Read: aclReadHookTrafficPermissions, + Write: aclWriteHookTrafficPermissions, List: resource.NoOpACLListHook, }, Validate: ValidateTrafficPermissions, @@ -29,12 +27,16 @@ func RegisterTrafficPermissions(r resource.Registry) { }) } -var MutateTrafficPermissions = resource.DecodeAndMutate(mutateTrafficPermissions) +func MutateTrafficPermissions(res *pbresource.Resource) error { + var tp pbauth.TrafficPermissions + + if err := res.Data.UnmarshalTo(&tp); err != nil { + return resource.NewErrDataParse(&tp, err) + } -func mutateTrafficPermissions(res *DecodedTrafficPermissions) (bool, error) { var changed bool - for _, p := range res.Data.Permissions { + for _, p := range tp.Permissions { for _, s := range p.Sources { if updated := normalizedTenancyForSource(s, res.Id.Tenancy); updated { changed = true @@ -42,7 +44,11 @@ func mutateTrafficPermissions(res *DecodedTrafficPermissions) (bool, error) { } } - return changed, nil + if !changed { + return nil + } + + return res.Data.MarshalFrom(&tp) } func normalizedTenancyForSource(src *pbauth.Source, parentTenancy *pbresource.Tenancy) bool { @@ -104,13 +110,17 @@ func firstNonEmptyString(a, b, c string) (string, bool) { return c, true } -var ValidateTrafficPermissions = resource.DecodeAndValidate(validateTrafficPermissions) +func ValidateTrafficPermissions(res *pbresource.Resource) error { + var tp pbauth.TrafficPermissions + + if err := res.Data.UnmarshalTo(&tp); err != nil { + return resource.NewErrDataParse(&tp, err) + } -func validateTrafficPermissions(res *DecodedTrafficPermissions) error { var merr error // enumcover:pbauth.Action - switch res.Data.Action { + switch tp.Action { case pbauth.Action_ACTION_ALLOW: case pbauth.Action_ACTION_DENY: case pbauth.Action_ACTION_UNSPECIFIED: @@ -122,14 +132,14 @@ func validateTrafficPermissions(res *DecodedTrafficPermissions) error { }) } - if res.Data.Destination == nil || (len(res.Data.Destination.IdentityName) == 0) { + if tp.Destination == nil || (len(tp.Destination.IdentityName) == 0) { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "data.destination", Wrapped: resource.ErrEmpty, }) } // Validate permissions - for i, permission := range res.Data.Permissions { + for i, permission := range tp.Permissions { wrapErr := func(err error) error { return resource.ErrInvalidListElement{ Name: "permissions", @@ -275,10 +285,30 @@ func isLocalPeer(p string) bool { return p == "local" || p == "" } -func aclReadHookTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *DecodedTrafficPermissions) error { - return authorizer.ToAllowAuthorizer().TrafficPermissionsReadAllowed(res.Data.Destination.IdentityName, authzContext) +func aclReadHookTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { + if res == nil { + return resource.ErrNeedResource + } + return authorizeDestination(res, func(dest string) error { + return authorizer.ToAllowAuthorizer().TrafficPermissionsReadAllowed(dest, authzContext) + }) } -func aclWriteHookTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *DecodedTrafficPermissions) error { - return authorizer.ToAllowAuthorizer().TrafficPermissionsWriteAllowed(res.Data.Destination.IdentityName, authzContext) +func aclWriteHookTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { + return authorizeDestination(res, func(dest string) error { + return authorizer.ToAllowAuthorizer().TrafficPermissionsWriteAllowed(dest, authzContext) + }) +} + +func authorizeDestination(res *pbresource.Resource, intentionAllowed func(string) error) error { + tp, err := resource.Decode[*pbauth.TrafficPermissions](res) + if err != nil { + return err + } + // Check intention:x permissions for identity + err = intentionAllowed(tp.Data.Destination.IdentityName) + if err != nil { + return err + } + return nil } diff --git a/internal/auth/internal/types/workload_identity.go b/internal/auth/internal/types/workload_identity.go index a15fd5bf5b2dd..17334e66099ef 100644 --- a/internal/auth/internal/types/workload_identity.go +++ b/internal/auth/internal/types/workload_identity.go @@ -10,8 +10,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedWorkloadIdentity = resource.DecodedResource[*pbauth.WorkloadIdentity] - func RegisterWorkloadIdentity(r resource.Registry) { r.Register(resource.Registration{ Type: pbauth.WorkloadIdentityType, @@ -22,17 +20,10 @@ func RegisterWorkloadIdentity(r resource.Registry) { Write: aclWriteHookWorkloadIdentity, List: resource.NoOpACLListHook, }, - Validate: ValidateWorkloadIdentity, + Validate: nil, }) } -var ValidateWorkloadIdentity = resource.DecodeAndValidate(validateWorkloadIdentity) - -func validateWorkloadIdentity(res *DecodedWorkloadIdentity) error { - // currently the WorkloadIdentity type has no fields. - return nil -} - func aclReadHookWorkloadIdentity( authorizer acl.Authorizer, authzCtx *acl.AuthorizerContext, diff --git a/internal/auth/internal/types/workload_identity_test.go b/internal/auth/internal/types/workload_identity_test.go index 19ed4cbeea87e..8dfb22bc74a2e 100644 --- a/internal/auth/internal/types/workload_identity_test.go +++ b/internal/auth/internal/types/workload_identity_test.go @@ -144,13 +144,3 @@ func TestWorkloadIdentityACLs(t *testing.T) { }) } } - -func TestWorkloadIdentity_ParseError(t *testing.T) { - rsc := resourcetest.Resource(pbauth.WorkloadIdentityType, "example"). - WithData(t, &pbauth.TrafficPermissions{}). - Build() - - err := ValidateWorkloadIdentity(rsc) - var parseErr resource.ErrDataParse - require.ErrorAs(t, err, &parseErr) -} diff --git a/internal/catalog/catalogtest/run_test.go b/internal/catalog/catalogtest/run_test.go index 5a6e1e62e3548..554900559e464 100644 --- a/internal/catalog/catalogtest/run_test.go +++ b/internal/catalog/catalogtest/run_test.go @@ -11,10 +11,15 @@ import ( "github.com/hashicorp/consul/internal/catalog/internal/controllers" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource/reaper" + rtest "github.com/hashicorp/consul/internal/resource/resourcetest" "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil" ) +var ( + clientOpts = rtest.ConfigureTestCLIFlags() +) + func runInMemResourceServiceAndControllers(t *testing.T, deps controllers.Dependencies) pbresource.ResourceServiceClient { t.Helper() @@ -38,10 +43,10 @@ func runInMemResourceServiceAndControllers(t *testing.T, deps controllers.Depend func TestControllers_Integration(t *testing.T) { client := runInMemResourceServiceAndControllers(t, catalog.DefaultControllerDependencies()) - RunCatalogV2Beta1IntegrationTest(t, client) + RunCatalogV2Beta1IntegrationTest(t, client, clientOpts.ClientOptions(t)...) } func TestControllers_Lifecycle(t *testing.T) { client := runInMemResourceServiceAndControllers(t, catalog.DefaultControllerDependencies()) - RunCatalogV2Beta1LifecycleIntegrationTest(t, client) + RunCatalogV2Beta1LifecycleIntegrationTest(t, client, clientOpts.ClientOptions(t)...) } diff --git a/internal/catalog/catalogtest/test_integration_v2beta1.go b/internal/catalog/catalogtest/test_integration_v2beta1.go index 79ffea7e79539..6d5c5854d7b00 100644 --- a/internal/catalog/catalogtest/test_integration_v2beta1.go +++ b/internal/catalog/catalogtest/test_integration_v2beta1.go @@ -26,7 +26,7 @@ var ( testData embed.FS ) -// RunCatalogV2Beta1IntegrationTest will push up a bunch of catalog related data and then +// RunCatalogV1Alpha1IntegrationTest will push up a bunch of catalog related data and then // verify that all the expected reconciliations happened correctly. This test is // intended to exercise a large swathe of behavior of the overall catalog package. // Besides just controller reconciliation behavior, the intent is also to verify @@ -38,19 +38,19 @@ var ( // is another RunCatalogIntegrationTestLifeCycle function that can be used for those // purposes. The two are distinct so that the data being published and the assertions // made against the system can be reused in upgrade tests. -func RunCatalogV2Beta1IntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { +func RunCatalogV2Beta1IntegrationTest(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) { t.Helper() - PublishCatalogV2Beta1IntegrationTestData(t, client) + PublishCatalogV2Beta1IntegrationTestData(t, client, opts...) VerifyCatalogV2Beta1IntegrationTestResults(t, client) } // PublishCatalogV2Beta1IntegrationTestData will perform a whole bunch of resource writes // for Service, ServiceEndpoints, Workload, Node and HealthStatus objects -func PublishCatalogV2Beta1IntegrationTestData(t *testing.T, client pbresource.ResourceServiceClient) { +func PublishCatalogV2Beta1IntegrationTestData(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) { t.Helper() - c := rtest.NewClient(client) + c := rtest.NewClient(client, opts...) resources := rtest.ParseResourcesFromFilesystem(t, testData, "integration_test_data/v2beta1") c.PublishResources(t, resources) diff --git a/internal/catalog/catalogtest/test_lifecycle_v2beta1.go b/internal/catalog/catalogtest/test_lifecycle_v2beta1.go index ea935dd4c56b7..5093b516cf421 100644 --- a/internal/catalog/catalogtest/test_lifecycle_v2beta1.go +++ b/internal/catalog/catalogtest/test_lifecycle_v2beta1.go @@ -16,19 +16,19 @@ import ( // RunCatalogV2Beta1LifecycleIntegrationTest intends to excercise functionality of // managing catalog resources over their normal lifecycle where they will be modified // several times, change state etc. -func RunCatalogV2Beta1LifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { +func RunCatalogV2Beta1LifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) { t.Helper() testutil.RunStep(t, "node-lifecycle", func(t *testing.T) { - RunCatalogV2Beta1NodeLifecycleIntegrationTest(t, client) + RunCatalogV2Beta1NodeLifecycleIntegrationTest(t, client, opts...) }) testutil.RunStep(t, "workload-lifecycle", func(t *testing.T) { - RunCatalogV2Beta1WorkloadLifecycleIntegrationTest(t, client) + RunCatalogV2Beta1WorkloadLifecycleIntegrationTest(t, client, opts...) }) testutil.RunStep(t, "endpoints-lifecycle", func(t *testing.T) { - RunCatalogV2Beta1EndpointsLifecycleIntegrationTest(t, client) + RunCatalogV2Beta1EndpointsLifecycleIntegrationTest(t, client, opts...) }) } @@ -41,8 +41,8 @@ func RunCatalogV2Beta1LifecycleIntegrationTest(t *testing.T, client pbresource.R // * Changing HealthStatus to a better health will cause recomputation of the Health // * Deletion of associated HealthStatuses will recompute the Health (back to passing) // * Deletion of the node will cause deletion of associated health statuses -func RunCatalogV2Beta1NodeLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { - c := rtest.NewClient(client) +func RunCatalogV2Beta1NodeLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) { + c := rtest.NewClient(client, opts...) nodeName := "test-lifecycle" nodeHealthName := "test-lifecycle-node-status" @@ -131,8 +131,8 @@ func RunCatalogV2Beta1NodeLifecycleIntegrationTest(t *testing.T, client pbresour // - Overall health is computed as the worst health amongst the nodes health and all // of the workloads associated HealthStatuses // - Deletion of the workload will cause deletion of all associated health statuses. -func RunCatalogV2Beta1WorkloadLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { - c := rtest.NewClient(client) +func RunCatalogV2Beta1WorkloadLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) { + c := rtest.NewClient(client, opts...) testutil.RunStep(t, "nodeless-workload", func(t *testing.T) { runV2Beta1NodelessWorkloadLifecycleIntegrationTest(t, c) }) @@ -379,8 +379,8 @@ func runV2Beta1NodeAssociatedWorkloadLifecycleIntegrationTest(t *testing.T, c *r // * Adding ports to a service will recalculate the endpoints // * Removing ports from a service will recalculate the endpoints // * Changing the workload will recalculate the endpoints (ports, addresses, or health) -func RunCatalogV2Beta1EndpointsLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient) { - c := rtest.NewClient(client) +func RunCatalogV2Beta1EndpointsLifecycleIntegrationTest(t *testing.T, client pbresource.ResourceServiceClient, opts ...rtest.ClientOption) { + c := rtest.NewClient(client, opts...) serviceName := "test-lifecycle" // Create the service without a selector. We should not see endpoints generated but we should see the diff --git a/internal/catalog/internal/controllers/workloadhealth/controller_test.go b/internal/catalog/internal/controllers/workloadhealth/controller_test.go index ba72b9934f94e..9a00a940a07e0 100644 --- a/internal/catalog/internal/controllers/workloadhealth/controller_test.go +++ b/internal/catalog/internal/controllers/workloadhealth/controller_test.go @@ -6,20 +6,17 @@ package workloadhealth import ( "context" "fmt" - "testing" - "time" - "github.com/hashicorp/consul/internal/resource" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" "google.golang.org/protobuf/testing/protocmp" + "testing" + "time" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" - svc "github.com/hashicorp/consul/agent/grpc-external/services/resource" svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/catalog/internal/controllers/nodehealth" "github.com/hashicorp/consul/internal/catalog/internal/mappers/nodemapper" "github.com/hashicorp/consul/internal/catalog/internal/types" @@ -48,15 +45,10 @@ var ( } ) -func resourceID(rtype *pbresource.Type, name string, tenancy *pbresource.Tenancy) *pbresource.ID { - defaultTenancy := resource.DefaultNamespacedTenancy() - if tenancy != nil { - defaultTenancy = tenancy - } - +func resourceID(rtype *pbresource.Type, name string) *pbresource.ID { return &pbresource.ID{ Type: rtype, - Tenancy: defaultTenancy, + Tenancy: resource.DefaultNamespacedTenancy(), Name: name, } } @@ -87,31 +79,18 @@ type controllerSuite struct { suite.Suite client pbresource.ResourceServiceClient runtime controller.Runtime - - isEnterprise bool - tenancies []*pbresource.Tenancy } func (suite *controllerSuite) SetupTest() { - suite.tenancies = resourcetest.TestTenancies() - mockTenancyBridge := &svc.MockTenancyBridge{} - for _, tenancy := range suite.tenancies { - mockTenancyBridge.On("PartitionExists", tenancy.Partition).Return(true, nil) - mockTenancyBridge.On("IsPartitionMarkedForDeletion", tenancy.Partition).Return(false, nil) - mockTenancyBridge.On("NamespaceExists", tenancy.Partition, tenancy.Namespace).Return(true, nil) - mockTenancyBridge.On("IsNamespaceMarkedForDeletion", tenancy.Partition, tenancy.Namespace).Return(false, nil) - } - - suite.client = svctest.RunResourceServiceWithConfig(suite.T(), svc.Config{TenancyBridge: mockTenancyBridge}, types.Register) + suite.client = svctest.RunResourceService(suite.T(), types.Register) suite.runtime = controller.Runtime{Client: suite.client, Logger: testutil.Logger(suite.T())} - suite.isEnterprise = (structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default") } // injectNodeWithStatus is a helper method to write a Node resource and synthesize its status // in a manner consistent with the node-health controller. This allows us to not actually // run and test the node-health controller but consume its "api" in the form of how // it encodes status. -func (suite *controllerSuite) injectNodeWithStatus(name string, health pbcatalog.Health, tenancy *pbresource.Tenancy) *pbresource.Resource { +func (suite *controllerSuite) injectNodeWithStatus(name string, health pbcatalog.Health) *pbresource.Resource { suite.T().Helper() state := pbresource.Condition_STATE_TRUE if health >= pbcatalog.Health_HEALTH_WARNING { @@ -120,7 +99,6 @@ func (suite *controllerSuite) injectNodeWithStatus(name string, health pbcatalog return resourcetest.Resource(pbcatalog.NodeType, name). WithData(suite.T(), nodeData). - WithTenancy(tenancy). WithStatus(nodehealth.StatusKey, &pbresource.Status{ Conditions: []*pbresource.Condition{ { @@ -164,20 +142,18 @@ func (suite *workloadHealthControllerTestSuite) SetupTest() { // // * The node to workload association is now being tracked by the node mapper // * The workloads status was updated and now matches the expected value -func (suite *workloadHealthControllerTestSuite) testReconcileWithNode(nodeHealth, workloadHealth pbcatalog.Health, tenancy *pbresource.Tenancy, status *pbresource.Condition) *pbresource.Resource { +func (suite *workloadHealthControllerTestSuite) testReconcileWithNode(nodeHealth, workloadHealth pbcatalog.Health, status *pbresource.Condition) *pbresource.Resource { suite.T().Helper() - node := suite.injectNodeWithStatus("test-node", nodeHealth, tenancy) + node := suite.injectNodeWithStatus("test-node", nodeHealth) workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). WithData(suite.T(), workloadData(node.Id.Name)). - WithTenancy(tenancy). Write(suite.T(), suite.client) resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: workloadHealth}). WithOwner(workload.Id). - WithTenancy(tenancy). Write(suite.T(), suite.client) err := suite.reconciler.Reconcile(context.Background(), suite.runtime, controller.Request{ @@ -213,16 +189,14 @@ func (suite *workloadHealthControllerTestSuite) testReconcileWithNode(nodeHealth // This is really just a tirmmed down version of testReconcileWithNode. It seemed // simpler and easier to read if these were two separate methods instead of combining // them in one with more branching based off of detecting whether nodes are in use. -func (suite *workloadHealthControllerTestSuite) testReconcileWithoutNode(workloadHealth pbcatalog.Health, tenancy *pbresource.Tenancy, status *pbresource.Condition) *pbresource.Resource { +func (suite *workloadHealthControllerTestSuite) testReconcileWithoutNode(workloadHealth pbcatalog.Health, status *pbresource.Condition) *pbresource.Resource { suite.T().Helper() workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). WithData(suite.T(), workloadData("")). - WithTenancy(tenancy). Write(suite.T(), suite.client) resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: workloadHealth}). - WithTenancy(tenancy). WithOwner(workload.Id). Write(suite.T(), suite.client) @@ -382,13 +356,11 @@ func (suite *workloadHealthControllerTestSuite) TestReconcile() { for name, tcase := range cases { suite.Run(name, func() { - suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - if tcase.nodeHealth != pbcatalog.Health_HEALTH_ANY { - suite.testReconcileWithNode(tcase.nodeHealth, tcase.workloadHealth, tenancy, tcase.expectedStatus) - } else { - suite.testReconcileWithoutNode(tcase.workloadHealth, tenancy, tcase.expectedStatus) - } - }) + if tcase.nodeHealth != pbcatalog.Health_HEALTH_ANY { + suite.testReconcileWithNode(tcase.nodeHealth, tcase.workloadHealth, tcase.expectedStatus) + } else { + suite.testReconcileWithoutNode(tcase.workloadHealth, tcase.expectedStatus) + } }) } } @@ -400,60 +372,56 @@ func (suite *workloadHealthControllerTestSuite) TestReconcileReadError() { // Passing a resource with an unknown type isn't particularly realistic as the controller // manager running our reconciliation will ensure all resource ids used are valid. However // its a really easy way right not to force the error. - suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - id := resourceID(fakeType, "blah", tenancy) + id := resourceID(fakeType, "blah") - err := suite.reconciler.Reconcile(context.Background(), suite.runtime, controller.Request{ID: id}) - require.Error(suite.T(), err) - require.Equal(suite.T(), codes.InvalidArgument, status.Code(err)) - }) + err := suite.reconciler.Reconcile(context.Background(), suite.runtime, controller.Request{ID: id}) + require.Error(suite.T(), err) + require.Equal(suite.T(), codes.InvalidArgument, status.Code(err)) } func (suite *workloadHealthControllerTestSuite) TestReconcileNotFound() { // This test wants to ensure that tracking for a workload is removed when the workload is deleted // so this test will inject the tracking, issue the Reconcile call which will get a // not found error and then ensure that the tracking was removed. - suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). - WithData(suite.T(), workloadData("test-node")). - // don't write this because then in the call to reconcile the resource - // would be found and defeat the purpose of the tes - WithTenancy(tenancy). - Build() - - node := resourcetest.Resource(pbcatalog.NodeType, "test-node"). - WithData(suite.T(), nodeData). - WithTenancy(tenancy). - // Whether this gets written or not doesn't matter - Build() - - // Track the workload - this simulates a previous round of reconciliation - // where the workload existed and was associated to the node. Other tests - // will cover more of the lifecycle of the controller so for the purposes - // of this test we can just inject it ourselves. - suite.mapper.TrackWorkload(workload.Id, node.Id) - - // check that the worklooad is in fact tracked properly - reqs, err := suite.mapper.MapNodeToWorkloads(context.Background(), suite.runtime, node) - - require.NoError(suite.T(), err) - require.Len(suite.T(), reqs, 1) - prototest.AssertDeepEqual(suite.T(), workload.Id, reqs[0].ID) - - // This workload was never actually inserted so the request should return a NotFound - // error and remove the workload from tracking - require.NoError( - suite.T(), - suite.reconciler.Reconcile( - context.Background(), - suite.runtime, - controller.Request{ID: workload.Id})) - - // Check the mapper again to ensure the node:workload association was removed. - reqs, err = suite.mapper.MapNodeToWorkloads(context.Background(), suite.runtime, node) - require.NoError(suite.T(), err) - require.Empty(suite.T(), reqs) - }) + + workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). + WithData(suite.T(), workloadData("test-node")). + // don't write this because then in the call to reconcile the resource + // would be found and defeat the purpose of the tes + WithTenancy(resource.DefaultNamespacedTenancy()). + Build() + + node := resourcetest.Resource(pbcatalog.NodeType, "test-node"). + WithData(suite.T(), nodeData). + // Whether this gets written or not doesn't matter + Build() + + // Track the workload - this simulates a previous round of reconciliation + // where the workload existed and was associated to the node. Other tests + // will cover more of the lifecycle of the controller so for the purposes + // of this test we can just inject it ourselves. + suite.mapper.TrackWorkload(workload.Id, node.Id) + + // check that the worklooad is in fact tracked properly + reqs, err := suite.mapper.MapNodeToWorkloads(context.Background(), suite.runtime, node) + + require.NoError(suite.T(), err) + require.Len(suite.T(), reqs, 1) + prototest.AssertDeepEqual(suite.T(), workload.Id, reqs[0].ID) + + // This workload was never actually inserted so the request should return a NotFound + // error and remove the workload from tracking + require.NoError( + suite.T(), + suite.reconciler.Reconcile( + context.Background(), + suite.runtime, + controller.Request{ID: workload.Id})) + + // Check the mapper again to ensure the node:workload association was removed. + reqs, err = suite.mapper.MapNodeToWorkloads(context.Background(), suite.runtime, node) + require.NoError(suite.T(), err) + require.Empty(suite.T(), reqs) } func (suite *workloadHealthControllerTestSuite) TestGetNodeHealthError() { @@ -466,30 +434,25 @@ func (suite *workloadHealthControllerTestSuite) TestGetNodeHealthError() { // but the exact error isn't very relevant to the core reason this // test exists. - suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - node := resourcetest.Resource(pbcatalog.NodeType, "test-node"). - WithData(suite.T(), nodeData). - WithTenancy(tenancy). - Write(suite.T(), suite.client) - - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). - WithData(suite.T(), workloadData(node.Id.Name)). - WithTenancy(tenancy). - Write(suite.T(), suite.client) - - resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). - WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_CRITICAL}). - WithOwner(workload.Id). - WithTenancy(tenancy). - Write(suite.T(), suite.client) - - err := suite.reconciler.Reconcile(context.Background(), suite.runtime, controller.Request{ - ID: workload.Id, - }) + node := resourcetest.Resource(pbcatalog.NodeType, "test-node"). + WithData(suite.T(), nodeData). + Write(suite.T(), suite.client) + + workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + WithData(suite.T(), workloadData(node.Id.Name)). + Write(suite.T(), suite.client) - require.Error(suite.T(), err) - require.Equal(suite.T(), errNodeUnreconciled, err) + resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). + WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_CRITICAL}). + WithOwner(workload.Id). + Write(suite.T(), suite.client) + + err := suite.reconciler.Reconcile(context.Background(), suite.runtime, controller.Request{ + ID: workload.Id, }) + + require.Error(suite.T(), err) + require.Equal(suite.T(), errNodeUnreconciled, err) } func (suite *workloadHealthControllerTestSuite) TestReconcile_AvoidReconciliationWrite() { @@ -498,26 +461,24 @@ func (suite *workloadHealthControllerTestSuite) TestReconcile_AvoidReconciliatio // we check that calling Reconcile twice in a row without any actual health change // doesn't bump the Version (which would increased for any write of the resource // or its status) - suite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - status := &pbresource.Condition{ - Type: StatusConditionHealthy, - State: pbresource.Condition_STATE_FALSE, - Reason: "HEALTH_WARNING", - Message: WorkloadUnhealthyMessage, - } - res1 := suite.testReconcileWithoutNode(pbcatalog.Health_HEALTH_WARNING, tenancy, status) + status := &pbresource.Condition{ + Type: StatusConditionHealthy, + State: pbresource.Condition_STATE_FALSE, + Reason: "HEALTH_WARNING", + Message: WorkloadUnhealthyMessage, + } + res1 := suite.testReconcileWithoutNode(pbcatalog.Health_HEALTH_WARNING, status) - err := suite.reconciler.Reconcile(context.Background(), suite.runtime, controller.Request{ID: res1.Id}) - require.NoError(suite.T(), err) + err := suite.reconciler.Reconcile(context.Background(), suite.runtime, controller.Request{ID: res1.Id}) + require.NoError(suite.T(), err) - // check that the status hasn't changed - res2 := suite.checkWorkloadStatus(res1.Id, status) + // check that the status hasn't changed + res2 := suite.checkWorkloadStatus(res1.Id, status) - // If another status write was performed then the versions would differ. This - // therefore proves that after a second reconciliation without any change - // in status that the controller is not making extra status writes. - require.Equal(suite.T(), res1.Version, res2.Version) - }) + // If another status write was performed then the versions would differ. This + // therefore proves that after a second reconciliation without any change + // in status that the controller is not making extra status writes. + require.Equal(suite.T(), res1.Version, res2.Version) } func (suite *workloadHealthControllerTestSuite) TestController() { @@ -537,52 +498,47 @@ func (suite *workloadHealthControllerTestSuite) TestController() { // run the manager go mgr.Run(ctx) - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - node := suite.injectNodeWithStatus("test-node", pbcatalog.Health_HEALTH_PASSING, tenancy) - - // create the workload - workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). - WithData(suite.T(), workloadData(node.Id.Name)). - WithTenancy(tenancy). - Write(suite.T(), suite.client) - - // Wait for reconciliation to occur and mark the workload as passing. - suite.waitForReconciliation(workload.Id, "HEALTH_PASSING") - - // Simulate a node unhealthy - suite.injectNodeWithStatus("test-node", pbcatalog.Health_HEALTH_WARNING, tenancy) - - // Wait for reconciliation to occur and mark the workload as warning - // due to the node going into the warning state. - suite.waitForReconciliation(workload.Id, "HEALTH_WARNING") - - // Now register a critical health check that should supercede the nodes - // warning status - - resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). - WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_CRITICAL}). - WithOwner(workload.Id). - WithTenancy(tenancy). - Write(suite.T(), suite.client) - - // Wait for reconciliation to occur again and mark the workload as unhealthy - suite.waitForReconciliation(workload.Id, "HEALTH_CRITICAL") - - // Put the health status back into a passing state and delink the node - resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). - WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_PASSING}). - WithOwner(workload.Id). - WithTenancy(tenancy). - Write(suite.T(), suite.client) - workload = resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). - WithData(suite.T(), workloadData("")). - WithTenancy(tenancy). - Write(suite.T(), suite.client) - - // Now that the workload health is passing and its not associated with the node its status should - // eventually become passing - suite.waitForReconciliation(workload.Id, "HEALTH_PASSING") - }) + // create a node to link things with + node := suite.injectNodeWithStatus("test-node", pbcatalog.Health_HEALTH_PASSING) + + // create the workload + workload := resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + WithData(suite.T(), workloadData(node.Id.Name)). + Write(suite.T(), suite.client) + + // Wait for reconciliation to occur and mark the workload as passing. + suite.waitForReconciliation(workload.Id, "HEALTH_PASSING") + + // Simulate a node unhealthy + suite.injectNodeWithStatus("test-node", pbcatalog.Health_HEALTH_WARNING) + + // Wait for reconciliation to occur and mark the workload as warning + // due to the node going into the warning state. + suite.waitForReconciliation(workload.Id, "HEALTH_WARNING") + + // Now register a critical health check that should supercede the nodes + // warning status + + resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). + WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_CRITICAL}). + WithOwner(workload.Id). + Write(suite.T(), suite.client) + + // Wait for reconciliation to occur again and mark the workload as unhealthy + suite.waitForReconciliation(workload.Id, "HEALTH_CRITICAL") + + // Put the health status back into a passing state and delink the node + resourcetest.Resource(pbcatalog.HealthStatusType, "test-status"). + WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: pbcatalog.Health_HEALTH_PASSING}). + WithOwner(workload.Id). + Write(suite.T(), suite.client) + workload = resourcetest.Resource(pbcatalog.WorkloadType, "test-workload"). + WithData(suite.T(), workloadData("")). + Write(suite.T(), suite.client) + + // Now that the workload health is passing and its not associated with the node its status should + // eventually become passing + suite.waitForReconciliation(workload.Id, "HEALTH_PASSING") } // wait for reconciliation is a helper to check if a resource has been reconciled and @@ -613,7 +569,7 @@ type getWorkloadHealthTestSuite struct { controllerSuite } -func (suite *getWorkloadHealthTestSuite) addHealthStatuses(workload *pbresource.ID, tenancy *pbresource.Tenancy, desiredHealth pbcatalog.Health) { +func (suite *getWorkloadHealthTestSuite) addHealthStatuses(workload *pbresource.ID, desiredHealth pbcatalog.Health) { // In order to exercise the behavior to ensure that the ordering a health status is // seen doesn't matter this is strategically naming health status so that they will be // returned in an order with the most precedent status being in the middle of the list. @@ -634,7 +590,6 @@ func (suite *getWorkloadHealthTestSuite) addHealthStatuses(workload *pbresource. if desiredHealth >= health { resourcetest.Resource(pbcatalog.HealthStatusType, fmt.Sprintf("check-%s-%d", workload.Name, idx)). WithData(suite.T(), &pbcatalog.HealthStatus{Type: "tcp", Status: health}). - WithTenancy(tenancy). WithOwner(workload). Write(suite.T(), suite.client) } @@ -646,28 +601,23 @@ func (suite *getWorkloadHealthTestSuite) TestListError() { // getWorkloadHealth. When the resource listing fails, we want to // propagate the error which should eventually result in retrying // the operation. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - health, err := getWorkloadHealth(context.Background(), suite.runtime, resourceID(fakeType, "foo", tenancy)) + health, err := getWorkloadHealth(context.Background(), suite.runtime, resourceID(fakeType, "foo")) - require.Error(suite.T(), err) - require.Equal(suite.T(), codes.InvalidArgument, status.Code(err)) - require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) - }) + require.Error(suite.T(), err) + require.Equal(suite.T(), codes.InvalidArgument, status.Code(err)) + require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) } func (suite *getWorkloadHealthTestSuite) TestNoHealthStatuses() { // This test's goal is to ensure that when no HealthStatuses are owned by the // workload that the health is assumed to be passing. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). - WithData(suite.T(), workloadData("")). - WithTenancy(tenancy). - Write(suite.T(), suite.client) - - health, err := getWorkloadHealth(context.Background(), suite.runtime, workload.Id) - require.NoError(suite.T(), err) - require.Equal(suite.T(), pbcatalog.Health_HEALTH_PASSING, health) - }) + workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). + WithData(suite.T(), workloadData("")). + Write(suite.T(), suite.client) + + health, err := getWorkloadHealth(context.Background(), suite.runtime, workload.Id) + require.NoError(suite.T(), err) + require.Equal(suite.T(), pbcatalog.Health_HEALTH_PASSING, health) } func (suite *getWorkloadHealthTestSuite) TestWithStatuses() { @@ -676,27 +626,24 @@ func (suite *getWorkloadHealthTestSuite) TestWithStatuses() { // helper method is used to inject multiple statuses in a way such that // the resource service will return them in a predictable order and can // properly exercise the code. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - for value, status := range pbcatalog.Health_name { - health := pbcatalog.Health(value) - if health == pbcatalog.Health_HEALTH_ANY { - continue - } + for value, status := range pbcatalog.Health_name { + health := pbcatalog.Health(value) + if health == pbcatalog.Health_HEALTH_ANY { + continue + } - suite.Run(status, func() { - workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). - WithData(suite.T(), workloadData("")). - WithTenancy(tenancy). - Write(suite.T(), suite.client) + suite.Run(status, func() { + workload := resourcetest.Resource(pbcatalog.WorkloadType, "foo"). + WithData(suite.T(), workloadData("")). + Write(suite.T(), suite.client) - suite.addHealthStatuses(workload.Id, tenancy, health) + suite.addHealthStatuses(workload.Id, health) - actualHealth, err := getWorkloadHealth(context.Background(), suite.runtime, workload.Id) - require.NoError(suite.T(), err) - require.Equal(suite.T(), health, actualHealth) - }) - } - }) + actualHealth, err := getWorkloadHealth(context.Background(), suite.runtime, workload.Id) + require.NoError(suite.T(), err) + require.Equal(suite.T(), health, actualHealth) + }) + } } func TestGetWorkloadHealth(t *testing.T) { @@ -712,62 +659,53 @@ func (suite *getNodeHealthTestSuite) TestNotfound() { // present in the system results in a the critical health but no error. This situation // could occur when a linked node gets removed without the workloads being modified/removed. // When that occurs we want to steer traffic away from the linked node as soon as possible. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - health, err := getNodeHealth(context.Background(), suite.runtime, resourceID(pbcatalog.NodeType, "not-found", tenancy)) - require.NoError(suite.T(), err) - require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) - }) + health, err := getNodeHealth(context.Background(), suite.runtime, resourceID(pbcatalog.NodeType, "not-found")) + require.NoError(suite.T(), err) + require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) + } func (suite *getNodeHealthTestSuite) TestReadError() { // This test's goal is to ensure the getNodeHealth propagates unexpected errors from // its resource read call back to the caller. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - health, err := getNodeHealth(context.Background(), suite.runtime, resourceID(fakeType, "not-found", tenancy)) - require.Error(suite.T(), err) - require.Equal(suite.T(), codes.InvalidArgument, status.Code(err)) - require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) - }) + health, err := getNodeHealth(context.Background(), suite.runtime, resourceID(fakeType, "not-found")) + require.Error(suite.T(), err) + require.Equal(suite.T(), codes.InvalidArgument, status.Code(err)) + require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) } func (suite *getNodeHealthTestSuite) TestUnreconciled() { // This test's goal is to ensure that nodes with unreconciled health are deemed // critical. Basically, the workload health controller should defer calculating // the workload health until the associated nodes health is known. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - node := resourcetest.Resource(pbcatalog.NodeType, "unreconciled"). - WithData(suite.T(), nodeData). - WithTenancy(tenancy). - Write(suite.T(), suite.client). - GetId() - - health, err := getNodeHealth(context.Background(), suite.runtime, node) - require.Error(suite.T(), err) - require.Equal(suite.T(), errNodeUnreconciled, err) - require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) - }) + node := resourcetest.Resource(pbcatalog.NodeType, "unreconciled"). + WithData(suite.T(), nodeData). + Write(suite.T(), suite.client). + GetId() + + health, err := getNodeHealth(context.Background(), suite.runtime, node) + require.Error(suite.T(), err) + require.Equal(suite.T(), errNodeUnreconciled, err) + require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) } func (suite *getNodeHealthTestSuite) TestNoConditions() { // This test's goal is to ensure that if a node's health status doesn't have - // the expected condition then its deemed critical. This should never happen + // the expected condition then its deemedd critical. This should never happen // in the integrated system as the node health controller would have to be // buggy to add an empty status. However it could also indicate some breaking // change went in. Regardless, the code to handle this state is written // and it will be tested here. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - node := resourcetest.Resource(pbcatalog.NodeType, "no-conditions"). - WithData(suite.T(), nodeData). - WithTenancy(tenancy). - WithStatus(nodehealth.StatusKey, &pbresource.Status{}). - Write(suite.T(), suite.client). - GetId() - - health, err := getNodeHealth(context.Background(), suite.runtime, node) - require.Error(suite.T(), err) - require.Equal(suite.T(), errNodeHealthConditionNotFound, err) - require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) - }) + node := resourcetest.Resource(pbcatalog.NodeType, "no-conditions"). + WithData(suite.T(), nodeData). + WithStatus(nodehealth.StatusKey, &pbresource.Status{}). + Write(suite.T(), suite.client). + GetId() + + health, err := getNodeHealth(context.Background(), suite.runtime, node) + require.Error(suite.T(), err) + require.Equal(suite.T(), errNodeHealthConditionNotFound, err) + require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) } func (suite *getNodeHealthTestSuite) TestInvalidReason() { @@ -778,65 +716,48 @@ func (suite *getNodeHealthTestSuite) TestInvalidReason() { // controller to put it into this state. As users or other controllers could // potentially force it into this state by writing the status themselves, it // would be good to ensure the defined behavior works as expected. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - node := resourcetest.Resource(pbcatalog.NodeType, "invalid-reason"). - WithData(suite.T(), nodeData). - WithTenancy(tenancy). - WithStatus(nodehealth.StatusKey, &pbresource.Status{ - Conditions: []*pbresource.Condition{ - { - Type: nodehealth.StatusConditionHealthy, - State: pbresource.Condition_STATE_FALSE, - Reason: "INVALID_REASON", - }, + node := resourcetest.Resource(pbcatalog.NodeType, "invalid-reason"). + WithData(suite.T(), nodeData). + WithStatus(nodehealth.StatusKey, &pbresource.Status{ + Conditions: []*pbresource.Condition{ + { + Type: nodehealth.StatusConditionHealthy, + State: pbresource.Condition_STATE_FALSE, + Reason: "INVALID_REASON", }, - }). - Write(suite.T(), suite.client). - GetId() - - health, err := getNodeHealth(context.Background(), suite.runtime, node) - require.Error(suite.T(), err) - require.Equal(suite.T(), errNodeHealthInvalid, err) - require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) - }) + }, + }). + Write(suite.T(), suite.client). + GetId() + + health, err := getNodeHealth(context.Background(), suite.runtime, node) + require.Error(suite.T(), err) + require.Equal(suite.T(), errNodeHealthInvalid, err) + require.Equal(suite.T(), pbcatalog.Health_HEALTH_CRITICAL, health) } func (suite *getNodeHealthTestSuite) TestValidHealth() { // This test aims to ensure that all status that would be reported by the node-health // controller gets accurately detected and returned by the getNodeHealth function. - suite.controllerSuite.runTestCaseWithTenancies(func(tenancy *pbresource.Tenancy) { - for value, healthStr := range pbcatalog.Health_name { - health := pbcatalog.Health(value) - - // this is not a valid health that a health status - // may be in. - if health == pbcatalog.Health_HEALTH_ANY { - continue - } + for value, healthStr := range pbcatalog.Health_name { + health := pbcatalog.Health(value) - suite.T().Run(healthStr, func(t *testing.T) { - node := suite.injectNodeWithStatus("test-node", health, tenancy) - - actualHealth, err := getNodeHealth(context.Background(), suite.runtime, node.Id) - require.NoError(t, err) - require.Equal(t, health, actualHealth) - }) + // this is not a valid health that a health status + // may be in. + if health == pbcatalog.Health_HEALTH_ANY { + continue } - }) -} -func TestGetNodeHealth(t *testing.T) { - suite.Run(t, new(getNodeHealthTestSuite)) -} + suite.T().Run(healthStr, func(t *testing.T) { + node := suite.injectNodeWithStatus("test-node", health) -func (suite *controllerSuite) runTestCaseWithTenancies(testFunc func(*pbresource.Tenancy)) { - for _, tenancy := range suite.tenancies { - suite.Run(suite.appendTenancyInfo(tenancy), func() { - testFunc(tenancy) + actualHealth, err := getNodeHealth(context.Background(), suite.runtime, node.Id) + require.NoError(t, err) + require.Equal(t, health, actualHealth) }) } } -func (suite *controllerSuite) appendTenancyInfo(tenancy *pbresource.Tenancy) string { - return fmt.Sprintf("%s_Namespace_%s_Partition", tenancy.Namespace, tenancy.Partition) +func TestGetNodeHealth(t *testing.T) { + suite.Run(t, new(getNodeHealthTestSuite)) } diff --git a/internal/catalog/internal/types/acl_hooks.go b/internal/catalog/internal/types/acl_hooks.go index d9ddcb8e93cc1..8250767f72549 100644 --- a/internal/catalog/internal/types/acl_hooks.go +++ b/internal/catalog/internal/types/acl_hooks.go @@ -13,22 +13,31 @@ func aclReadHookResourceWithWorkloadSelector(authorizer acl.Authorizer, authzCon return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), authzContext) } -func aclWriteHookResourceWithWorkloadSelector[T WorkloadSelecting](authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, r *resource.DecodedResource[T]) error { +func aclWriteHookResourceWithWorkloadSelector[T WorkloadSelecting](authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { + if res == nil { + return resource.ErrNeedResource + } + + decodedService, err := resource.Decode[T](res) + if err != nil { + return resource.ErrNeedResource + } + // First check service:write on the name. - err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(r.GetId().GetName(), authzContext) + err = authorizer.ToAllowAuthorizer().ServiceWriteAllowed(res.GetId().GetName(), authzContext) if err != nil { return err } // Then also check whether we're allowed to select a service. - for _, name := range r.Data.GetWorkloads().GetNames() { + for _, name := range decodedService.GetData().GetWorkloads().GetNames() { err = authorizer.ToAllowAuthorizer().ServiceReadAllowed(name, authzContext) if err != nil { return err } } - for _, prefix := range r.Data.GetWorkloads().GetPrefixes() { + for _, prefix := range decodedService.GetData().GetWorkloads().GetPrefixes() { err = authorizer.ToAllowAuthorizer().ServiceReadPrefixAllowed(prefix, authzContext) if err != nil { return err @@ -41,7 +50,7 @@ func aclWriteHookResourceWithWorkloadSelector[T WorkloadSelecting](authorizer ac func ACLHooksForWorkloadSelectingType[T WorkloadSelecting]() *resource.ACLHooks { return &resource.ACLHooks{ Read: aclReadHookResourceWithWorkloadSelector, - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookResourceWithWorkloadSelector[T]), + Write: aclWriteHookResourceWithWorkloadSelector[T], List: resource.NoOpACLListHook, } } diff --git a/internal/catalog/internal/types/dns_policy.go b/internal/catalog/internal/types/dns_policy.go index 91dd2615455ca..8e9dd864a9573 100644 --- a/internal/catalog/internal/types/dns_policy.go +++ b/internal/catalog/internal/types/dns_policy.go @@ -10,10 +10,9 @@ import ( "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedDNSPolicy = resource.DecodedResource[*pbcatalog.DNSPolicy] - func RegisterDNSPolicy(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.DNSPolicyType, @@ -24,13 +23,17 @@ func RegisterDNSPolicy(r resource.Registry) { }) } -var ValidateDNSPolicy = resource.DecodeAndValidate(validateDNSPolicy) +func ValidateDNSPolicy(res *pbresource.Resource) error { + var policy pbcatalog.DNSPolicy + + if err := res.Data.UnmarshalTo(&policy); err != nil { + return resource.NewErrDataParse(&policy, err) + } -func validateDNSPolicy(res *DecodedDNSPolicy) error { var err error // Ensure that this resource isn't useless and is attempting to // select at least one workload. - if selErr := ValidateSelector(res.Data.Workloads, false); selErr != nil { + if selErr := ValidateSelector(policy.Workloads, false); selErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, @@ -38,7 +41,7 @@ func validateDNSPolicy(res *DecodedDNSPolicy) error { } // Validate the weights - if weightErr := validateDNSPolicyWeights(res.Data.Weights); weightErr != nil { + if weightErr := validateDNSPolicyWeights(policy.Weights); weightErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "weights", Wrapped: weightErr, diff --git a/internal/catalog/internal/types/failover_policy.go b/internal/catalog/internal/types/failover_policy.go index 012150fc046dc..047bb9a95b050 100644 --- a/internal/catalog/internal/types/failover_policy.go +++ b/internal/catalog/internal/types/failover_policy.go @@ -15,8 +15,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedFailoverPolicy = resource.DecodedResource[*pbcatalog.FailoverPolicy] - func RegisterFailoverPolicy(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.FailoverPolicyType, @@ -26,32 +24,36 @@ func RegisterFailoverPolicy(r resource.Registry) { Validate: ValidateFailoverPolicy, ACLs: &resource.ACLHooks{ Read: aclReadHookFailoverPolicy, - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookFailoverPolicy), + Write: aclWriteHookFailoverPolicy, List: resource.NoOpACLListHook, }, }) } -var MutateFailoverPolicy = resource.DecodeAndMutate(mutateFailoverPolicy) +func MutateFailoverPolicy(res *pbresource.Resource) error { + var failover pbcatalog.FailoverPolicy + + if err := res.Data.UnmarshalTo(&failover); err != nil { + return resource.NewErrDataParse(&failover, err) + } -func mutateFailoverPolicy(res *DecodedFailoverPolicy) (bool, error) { changed := false // Handle eliding empty configs. - if res.Data.Config != nil && res.Data.Config.IsEmpty() { - res.Data.Config = nil + if failover.Config != nil && failover.Config.IsEmpty() { + failover.Config = nil changed = true } - if res.Data.Config != nil { - if mutateFailoverConfig(res.Id.Tenancy, res.Data.Config) { + if failover.Config != nil { + if mutateFailoverConfig(res.Id.Tenancy, failover.Config) { changed = true } } - for port, pc := range res.Data.PortConfigs { + for port, pc := range failover.PortConfigs { if pc.IsEmpty() { - delete(res.Data.PortConfigs, port) + delete(failover.PortConfigs, port) changed = true } else { if mutateFailoverConfig(res.Id.Tenancy, pc) { @@ -59,12 +61,16 @@ func mutateFailoverPolicy(res *DecodedFailoverPolicy) (bool, error) { } } } - if len(res.Data.PortConfigs) == 0 { - res.Data.PortConfigs = nil + if len(failover.PortConfigs) == 0 { + failover.PortConfigs = nil changed = true } - return changed, nil + if !changed { + return nil + } + + return res.Data.MarshalFrom(&failover) } func mutateFailoverConfig(policyTenancy *pbresource.Tenancy, config *pbcatalog.FailoverConfig) (changed bool) { @@ -103,31 +109,35 @@ func isLocalPeer(p string) bool { return p == "local" || p == "" } -var ValidateFailoverPolicy = resource.DecodeAndValidate(validateFailoverPolicy) +func ValidateFailoverPolicy(res *pbresource.Resource) error { + var failover pbcatalog.FailoverPolicy + + if err := res.Data.UnmarshalTo(&failover); err != nil { + return resource.NewErrDataParse(&failover, err) + } -func validateFailoverPolicy(res *DecodedFailoverPolicy) error { var merr error - if res.Data.Config == nil && len(res.Data.PortConfigs) == 0 { + if failover.Config == nil && len(failover.PortConfigs) == 0 { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "config", Wrapped: fmt.Errorf("at least one of config or port_configs must be set"), }) } - if res.Data.Config != nil { + if failover.Config != nil { wrapConfigErr := func(err error) error { return resource.ErrInvalidField{ Name: "config", Wrapped: err, } } - if cfgErr := validateFailoverConfig(res.Data.Config, false, wrapConfigErr); cfgErr != nil { + if cfgErr := validateFailoverConfig(failover.Config, false, wrapConfigErr); cfgErr != nil { merr = multierror.Append(merr, cfgErr) } } - for portName, pc := range res.Data.PortConfigs { + for portName, pc := range failover.PortConfigs { wrapConfigErr := func(err error) error { return resource.ErrInvalidMapValue{ Map: "port_configs", @@ -323,7 +333,7 @@ func aclReadHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.Auth return authorizer.ToAllowAuthorizer().ServiceReadAllowed(serviceName, authzContext) } -func aclWriteHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *DecodedFailoverPolicy) error { +func aclWriteHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { // FailoverPolicy is name-aligned with Service serviceName := res.Id.Name @@ -332,10 +342,15 @@ func aclWriteHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.Aut return err } + dec, err := resource.Decode[*pbcatalog.FailoverPolicy](res) + if err != nil { + return err + } + // Ensure you have service:read on any destination that may be affected by // traffic FROM this config change. - if res.Data.Config != nil { - for _, dest := range res.Data.Config.Destinations { + if dec.Data.Config != nil { + for _, dest := range dec.Data.Config.Destinations { destAuthzContext := resource.AuthorizerContext(dest.Ref.GetTenancy()) destServiceName := dest.Ref.GetName() if err := authorizer.ToAllowAuthorizer().ServiceReadAllowed(destServiceName, destAuthzContext); err != nil { @@ -343,7 +358,7 @@ func aclWriteHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.Aut } } } - for _, pc := range res.Data.PortConfigs { + for _, pc := range dec.Data.PortConfigs { for _, dest := range pc.Destinations { destAuthzContext := resource.AuthorizerContext(dest.Ref.GetTenancy()) destServiceName := dest.Ref.GetName() diff --git a/internal/catalog/internal/types/health_checks.go b/internal/catalog/internal/types/health_checks.go index 3d819e12885aa..1333e2368d882 100644 --- a/internal/catalog/internal/types/health_checks.go +++ b/internal/catalog/internal/types/health_checks.go @@ -8,10 +8,9 @@ import ( "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedHealthChecks = resource.DecodedResource[*pbcatalog.HealthChecks] - func RegisterHealthChecks(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.HealthChecksType, @@ -22,13 +21,17 @@ func RegisterHealthChecks(r resource.Registry) { }) } -var ValidateHealthChecks = resource.DecodeAndValidate(validateHealthChecks) +func ValidateHealthChecks(res *pbresource.Resource) error { + var checks pbcatalog.HealthChecks + + if err := res.Data.UnmarshalTo(&checks); err != nil { + return resource.NewErrDataParse(&checks, err) + } -func validateHealthChecks(res *DecodedHealthChecks) error { var err error // Validate the workload selector - if selErr := ValidateSelector(res.Data.Workloads, false); selErr != nil { + if selErr := ValidateSelector(checks.Workloads, false); selErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, @@ -36,7 +39,7 @@ func validateHealthChecks(res *DecodedHealthChecks) error { } // Validate each check - for idx, check := range res.Data.HealthChecks { + for idx, check := range checks.HealthChecks { if checkErr := validateCheck(check); checkErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "checks", diff --git a/internal/catalog/internal/types/health_status.go b/internal/catalog/internal/types/health_status.go index c5ea7e106fa3b..fe92e858b025e 100644 --- a/internal/catalog/internal/types/health_status.go +++ b/internal/catalog/internal/types/health_status.go @@ -12,8 +12,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedHealthStatus = resource.DecodedResource[*pbcatalog.HealthStatus] - func RegisterHealthStatus(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.HealthStatusType, @@ -21,29 +19,33 @@ func RegisterHealthStatus(r resource.Registry) { Scope: resource.ScopeNamespace, Validate: ValidateHealthStatus, ACLs: &resource.ACLHooks{ - Read: resource.AuthorizeReadWithResource(aclReadHookHealthStatus), + Read: aclReadHookHealthStatus, Write: aclWriteHookHealthStatus, List: resource.NoOpACLListHook, }, }) } -var ValidateHealthStatus = resource.DecodeAndValidate(validateHealthStatus) +func ValidateHealthStatus(res *pbresource.Resource) error { + var hs pbcatalog.HealthStatus + + if err := res.Data.UnmarshalTo(&hs); err != nil { + return resource.NewErrDataParse(&hs, err) + } -func validateHealthStatus(res *DecodedHealthStatus) error { var err error // Should we allow empty types? I think for now it will be safest to require // the type field is set and we can relax this restriction in the future // if we deem it desirable. - if res.Data.Type == "" { + if hs.Type == "" { err = multierror.Append(err, resource.ErrInvalidField{ Name: "type", Wrapped: resource.ErrMissing, }) } - switch res.Data.Status { + switch hs.Status { case pbcatalog.Health_HEALTH_PASSING, pbcatalog.Health_HEALTH_WARNING, pbcatalog.Health_HEALTH_CRITICAL, @@ -59,7 +61,7 @@ func validateHealthStatus(res *DecodedHealthStatus) error { // owner is currently the resource that this HealthStatus applies to. If we // change this to be a parent reference within the HealthStatus.Data then // we could allow for other owners. - if res.Resource.Owner == nil { + if res.Owner == nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "owner", Wrapped: resource.ErrMissing, @@ -71,13 +73,15 @@ func validateHealthStatus(res *DecodedHealthStatus) error { return err } -func aclReadHookHealthStatus(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { +func aclReadHookHealthStatus(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { + if res == nil { + return resource.ErrNeedResource + } // For a health status of a workload we need to check service:read perms. if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.WorkloadType) { return authorizer.ToAllowAuthorizer().ServiceReadAllowed(res.GetOwner().GetName(), authzContext) } - // For a health status of a node we need to check node:read perms. if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.NodeType) { return authorizer.ToAllowAuthorizer().NodeReadAllowed(res.GetOwner().GetName(), authzContext) } @@ -91,7 +95,6 @@ func aclWriteHookHealthStatus(authorizer acl.Authorizer, authzContext *acl.Autho return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(res.GetOwner().GetName(), authzContext) } - // For a health status of a node we need to check node:write perms. if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.NodeType) { return authorizer.ToAllowAuthorizer().NodeWriteAllowed(res.GetOwner().GetName(), authzContext) } diff --git a/internal/catalog/internal/types/node.go b/internal/catalog/internal/types/node.go index 1ee68f22ca82e..42ac833c6e7d8 100644 --- a/internal/catalog/internal/types/node.go +++ b/internal/catalog/internal/types/node.go @@ -12,8 +12,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedNode = resource.DecodedResource[*pbcatalog.Node] - func RegisterNode(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.NodeType, @@ -33,12 +31,16 @@ func RegisterNode(r resource.Registry) { }) } -var ValidateNode = resource.DecodeAndValidate(validateNode) +func ValidateNode(res *pbresource.Resource) error { + var node pbcatalog.Node + + if err := res.Data.UnmarshalTo(&node); err != nil { + return resource.NewErrDataParse(&node, err) + } -func validateNode(res *DecodedNode) error { var err error // Validate that the node has at least 1 address - if len(res.Data.Addresses) < 1 { + if len(node.Addresses) < 1 { err = multierror.Append(err, resource.ErrInvalidField{ Name: "addresses", Wrapped: resource.ErrEmpty, @@ -46,7 +48,7 @@ func validateNode(res *DecodedNode) error { } // Validate each node address - for idx, addr := range res.Data.Addresses { + for idx, addr := range node.Addresses { if addrErr := validateNodeAddress(addr); addrErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "addresses", diff --git a/internal/catalog/internal/types/service.go b/internal/catalog/internal/types/service.go index bb56fe10a5710..a91f3a7c51801 100644 --- a/internal/catalog/internal/types/service.go +++ b/internal/catalog/internal/types/service.go @@ -10,10 +10,9 @@ import ( "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedService = resource.DecodedResource[*pbcatalog.Service] - func RegisterService(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.ServiceType, @@ -25,25 +24,37 @@ func RegisterService(r resource.Registry) { }) } -var MutateService = resource.DecodeAndMutate(mutateService) +func MutateService(res *pbresource.Resource) error { + var service pbcatalog.Service + + if err := res.Data.UnmarshalTo(&service); err != nil { + return err + } -func mutateService(res *DecodedService) (bool, error) { changed := false // Default service port protocols. - for _, port := range res.Data.Ports { + for _, port := range service.Ports { if port.Protocol == pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { port.Protocol = pbcatalog.Protocol_PROTOCOL_TCP changed = true } } - return changed, nil + if !changed { + return nil + } + + return res.Data.MarshalFrom(&service) } -var ValidateService = resource.DecodeAndValidate(validateService) +func ValidateService(res *pbresource.Resource) error { + var service pbcatalog.Service + + if err := res.Data.UnmarshalTo(&service); err != nil { + return resource.NewErrDataParse(&service, err) + } -func validateService(res *DecodedService) error { var err error // Validate the workload selector. We are allowing selectors with no @@ -51,7 +62,7 @@ func validateService(res *DecodedService) error { // ServiceEndpoints objects for this service such as when desiring to // configure endpoint information for external services that are not // registered as workloads - if selErr := ValidateSelector(res.Data.Workloads, true); selErr != nil { + if selErr := ValidateSelector(service.Workloads, true); selErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, @@ -61,7 +72,7 @@ func validateService(res *DecodedService) error { usedVirtualPorts := make(map[uint32]int) // Validate each port - for idx, port := range res.Data.Ports { + for idx, port := range service.Ports { if usedIdx, found := usedVirtualPorts[port.VirtualPort]; found { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "ports", @@ -119,7 +130,7 @@ func validateService(res *DecodedService) error { } // Validate that the Virtual IPs are all IP addresses - for idx, vip := range res.Data.VirtualIps { + for idx, vip := range service.VirtualIps { if vipErr := validateIPAddress(vip); vipErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "virtual_ips", diff --git a/internal/catalog/internal/types/service_endpoints.go b/internal/catalog/internal/types/service_endpoints.go index b78a1bc705fa5..1991c455ad901 100644 --- a/internal/catalog/internal/types/service_endpoints.go +++ b/internal/catalog/internal/types/service_endpoints.go @@ -14,8 +14,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedServiceEndpoints = resource.DecodedResource[*pbcatalog.ServiceEndpoints] - func RegisterServiceEndpoints(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.ServiceEndpointsType, @@ -47,9 +45,13 @@ func MutateServiceEndpoints(res *pbresource.Resource) error { return nil } -var ValidateServiceEndpoints = resource.DecodeAndValidate[*pbcatalog.ServiceEndpoints](validateServiceEndpoints) +func ValidateServiceEndpoints(res *pbresource.Resource) error { + var svcEndpoints pbcatalog.ServiceEndpoints + + if err := res.Data.UnmarshalTo(&svcEndpoints); err != nil { + return resource.NewErrDataParse(&svcEndpoints, err) + } -func validateServiceEndpoints(res *DecodedServiceEndpoints) error { var err error if !resource.EqualType(res.Owner.Type, pbcatalog.ServiceType) { err = multierror.Append(err, resource.ErrOwnerTypeInvalid{ @@ -76,8 +78,8 @@ func validateServiceEndpoints(res *DecodedServiceEndpoints) error { }) } - for idx, endpoint := range res.Data.Endpoints { - if endpointErr := validateEndpoint(endpoint, res.Resource); endpointErr != nil { + for idx, endpoint := range svcEndpoints.Endpoints { + if endpointErr := validateEndpoint(endpoint, res); endpointErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "endpoints", Index: idx, diff --git a/internal/catalog/internal/types/virtual_ips.go b/internal/catalog/internal/types/virtual_ips.go index be692f63ed65a..9c7a065474059 100644 --- a/internal/catalog/internal/types/virtual_ips.go +++ b/internal/catalog/internal/types/virtual_ips.go @@ -12,8 +12,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedVirtualIPs = resource.DecodedResource[*pbcatalog.VirtualIPs] - func RegisterVirtualIPs(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.VirtualIPsType, @@ -32,11 +30,15 @@ func RegisterVirtualIPs(r resource.Registry) { }) } -var ValidateVirtualIPs = resource.DecodeAndValidate(validateVirtualIPs) +func ValidateVirtualIPs(res *pbresource.Resource) error { + var vips pbcatalog.VirtualIPs + + if err := res.Data.UnmarshalTo(&vips); err != nil { + return resource.NewErrDataParse(&vips, err) + } -func validateVirtualIPs(res *DecodedVirtualIPs) error { var err error - for idx, ip := range res.Data.Ips { + for idx, ip := range vips.Ips { if vipErr := validateIPAddress(ip.Address); vipErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "ips", diff --git a/internal/catalog/internal/types/workload.go b/internal/catalog/internal/types/workload.go index 8535a6250491d..c09513a4a5b3d 100644 --- a/internal/catalog/internal/types/workload.go +++ b/internal/catalog/internal/types/workload.go @@ -15,8 +15,6 @@ import ( "github.com/hashicorp/consul/proto-public/pbresource" ) -type DecodedWorkload = resource.DecodedResource[*pbcatalog.Workload] - func RegisterWorkload(r resource.Registry) { r.Register(resource.Registration{ Type: pbcatalog.WorkloadType, @@ -25,19 +23,23 @@ func RegisterWorkload(r resource.Registry) { Validate: ValidateWorkload, ACLs: &resource.ACLHooks{ Read: aclReadHookWorkload, - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookWorkload), + Write: aclWriteHookWorkload, List: resource.NoOpACLListHook, }, }) } -var ValidateWorkload = resource.DecodeAndValidate(validateWorkload) +func ValidateWorkload(res *pbresource.Resource) error { + var workload pbcatalog.Workload + + if err := res.Data.UnmarshalTo(&workload); err != nil { + return resource.NewErrDataParse(&workload, err) + } -func validateWorkload(res *DecodedWorkload) error { var err error // Validate that the workload has at least one port - if len(res.Data.Ports) < 1 { + if len(workload.Ports) < 1 { err = multierror.Append(err, resource.ErrInvalidField{ Name: "ports", Wrapped: resource.ErrEmpty, @@ -47,7 +49,7 @@ func validateWorkload(res *DecodedWorkload) error { var meshPorts []string // Validate the Workload Ports - for portName, port := range res.Data.Ports { + for portName, port := range workload.Ports { if portNameErr := ValidatePortName(portName); portNameErr != nil { err = multierror.Append(err, resource.ErrInvalidMapKey{ Map: "ports", @@ -98,12 +100,12 @@ func validateWorkload(res *DecodedWorkload) error { // If the workload is mesh enabled then a valid identity must be provided. // If not mesh enabled but a non-empty identity is provided then we still // validate that its valid. - if len(meshPorts) > 0 && res.Data.Identity == "" { + if len(meshPorts) > 0 && workload.Identity == "" { err = multierror.Append(err, resource.ErrInvalidField{ Name: "identity", Wrapped: resource.ErrMissing, }) - } else if res.Data.Identity != "" && !isValidDNSLabel(res.Data.Identity) { + } else if workload.Identity != "" && !isValidDNSLabel(workload.Identity) { err = multierror.Append(err, resource.ErrInvalidField{ Name: "identity", Wrapped: errNotDNSLabel, @@ -111,7 +113,7 @@ func validateWorkload(res *DecodedWorkload) error { } // Validate workload locality - if res.Data.Locality != nil && res.Data.Locality.Region == "" && res.Data.Locality.Zone != "" { + if workload.Locality != nil && workload.Locality.Region == "" && workload.Locality.Zone != "" { err = multierror.Append(err, resource.ErrInvalidField{ Name: "locality", Wrapped: errLocalityZoneNoRegion, @@ -120,8 +122,8 @@ func validateWorkload(res *DecodedWorkload) error { // Node associations are optional but if present the name should // be a valid DNS label. - if res.Data.NodeName != "" { - if !isValidDNSLabel(res.Data.NodeName) { + if workload.NodeName != "" { + if !isValidDNSLabel(workload.NodeName) { err = multierror.Append(err, resource.ErrInvalidField{ Name: "node_name", Wrapped: errNotDNSLabel, @@ -129,7 +131,7 @@ func validateWorkload(res *DecodedWorkload) error { } } - if len(res.Data.Addresses) < 1 { + if len(workload.Addresses) < 1 { err = multierror.Append(err, resource.ErrInvalidField{ Name: "addresses", Wrapped: resource.ErrEmpty, @@ -137,8 +139,8 @@ func validateWorkload(res *DecodedWorkload) error { } // Validate Workload Addresses - for idx, addr := range res.Data.Addresses { - if addrErr := validateWorkloadAddress(addr, res.Data.Ports); addrErr != nil { + for idx, addr := range workload.Addresses { + if addrErr := validateWorkloadAddress(addr, workload.Ports); addrErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "addresses", Index: idx, @@ -154,21 +156,26 @@ func aclReadHookWorkload(authorizer acl.Authorizer, authzContext *acl.Authorizer return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), authzContext) } -func aclWriteHookWorkload(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *DecodedWorkload) error { +func aclWriteHookWorkload(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { + decodedWorkload, err := resource.Decode[*pbcatalog.Workload](res) + if err != nil { + return resource.ErrNeedResource + } + // First check service:write on the workload name. - err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(res.GetId().GetName(), authzContext) + err = authorizer.ToAllowAuthorizer().ServiceWriteAllowed(res.GetId().GetName(), authzContext) if err != nil { return err } // Check node:read permissions if node is specified. - if res.Data.GetNodeName() != "" { - return authorizer.ToAllowAuthorizer().NodeReadAllowed(res.Data.GetNodeName(), authzContext) + if decodedWorkload.GetData().GetNodeName() != "" { + return authorizer.ToAllowAuthorizer().NodeReadAllowed(decodedWorkload.GetData().GetNodeName(), authzContext) } // Check identity:read permissions if identity is specified. - if res.Data.GetIdentity() != "" { - return authorizer.ToAllowAuthorizer().IdentityReadAllowed(res.Data.GetIdentity(), authzContext) + if decodedWorkload.GetData().GetIdentity() != "" { + return authorizer.ToAllowAuthorizer().IdentityReadAllowed(decodedWorkload.GetData().GetIdentity(), authzContext) } return nil diff --git a/internal/controller/api_test.go b/internal/controller/api_test.go index e80458541008f..40d3ec99bebdb 100644 --- a/internal/controller/api_test.go +++ b/internal/controller/api_test.go @@ -242,86 +242,6 @@ func TestController_NoReconciler(t *testing.T) { func() { mgr.Register(ctrl) }) } -func TestController_Watch(t *testing.T) { - t.Parallel() - - t.Run("partitioned scoped resources", func(t *testing.T) { - rec := newTestReconciler() - - client := svctest.RunResourceService(t, demo.RegisterTypes) - - ctrl := controller. - ForType(demo.TypeV1RecordLabel). - WithReconciler(rec) - - mgr := controller.NewManager(client, testutil.Logger(t)) - mgr.SetRaftLeader(true) - mgr.Register(ctrl) - - ctx := testContext(t) - go mgr.Run(ctx) - - res, err := demo.GenerateV1RecordLabel("test") - require.NoError(t, err) - - rsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: res}) - require.NoError(t, err) - - req := rec.wait(t) - prototest.AssertDeepEqual(t, rsp.Resource.Id, req.ID) - }) - - t.Run("cluster scoped resources", func(t *testing.T) { - rec := newTestReconciler() - - client := svctest.RunResourceService(t, demo.RegisterTypes) - - ctrl := controller. - ForType(demo.TypeV1Executive). - WithReconciler(rec) - - mgr := controller.NewManager(client, testutil.Logger(t)) - mgr.SetRaftLeader(true) - mgr.Register(ctrl) - - go mgr.Run(testContext(t)) - - exec, err := demo.GenerateV1Executive("test", "CEO") - require.NoError(t, err) - - rsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: exec}) - require.NoError(t, err) - - req := rec.wait(t) - prototest.AssertDeepEqual(t, rsp.Resource.Id, req.ID) - }) - - t.Run("namespace scoped resources", func(t *testing.T) { - rec := newTestReconciler() - - client := svctest.RunResourceService(t, demo.RegisterTypes) - - ctrl := controller. - ForType(demo.TypeV2Artist). - WithReconciler(rec) - - mgr := controller.NewManager(client, testutil.Logger(t)) - mgr.SetRaftLeader(true) - mgr.Register(ctrl) - - go mgr.Run(testContext(t)) - - artist, err := demo.GenerateV2Artist() - require.NoError(t, err) - - rsp, err := client.Write(testContext(t), &pbresource.WriteRequest{Resource: artist}) - require.NoError(t, err) - - req := rec.wait(t) - prototest.AssertDeepEqual(t, rsp.Resource.Id, req.ID) - }) -} - func newTestReconciler() *testReconciler { return &testReconciler{ calls: make(chan controller.Request), diff --git a/internal/controller/controller.go b/internal/controller/controller.go index 97955db6a3c15..ac901d355b6e3 100644 --- a/internal/controller/controller.go +++ b/internal/controller/controller.go @@ -14,6 +14,7 @@ import ( "github.com/hashicorp/consul/agent/consul/controller/queue" "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/internal/storage" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -91,6 +92,11 @@ func runQueue[T queue.ItemType](ctx context.Context, ctrl Controller) queue.Work func (c *controllerRunner) watch(ctx context.Context, typ *pbresource.Type, add func(*pbresource.Resource)) error { wl, err := c.client.WatchList(ctx, &pbresource.WatchListRequest{ Type: typ, + Tenancy: &pbresource.Tenancy{ + Partition: storage.Wildcard, + PeerName: storage.Wildcard, + Namespace: storage.Wildcard, + }, }) if err != nil { c.logger.Error("failed to create watch", "error", err) diff --git a/internal/controller/dependencies.go b/internal/controller/dependencies.go deleted file mode 100644 index 6a91d91ff7b72..0000000000000 --- a/internal/controller/dependencies.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controller - -import ( - "fmt" - "sort" - "strings" - - "github.com/hashicorp/go-multierror" - - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func (m *Manager) ValidateDependencies(registrations []resource.Registration) error { - deps := m.CalculateDependencies(registrations) - - return deps.validate() -} - -type Dependencies map[string][]string - -func (deps Dependencies) validate() error { - var merr error - seen := make(map[string]map[string]struct{}) - - mkErr := func(src, dst string) error { - vals := []string{src, dst} - sort.Strings(vals) - return fmt.Errorf("circular dependency between %q and %q", vals[0], vals[1]) - } - - for src, dsts := range deps { - seenDsts := seen[src] - if len(seenDsts) == 0 { - seen[src] = make(map[string]struct{}) - } - - for _, dst := range dsts { - if _, ok := seenDsts[dst]; ok { - merr = multierror.Append(merr, mkErr(src, dst)) - } - - if inverseDsts := seen[dst]; len(inverseDsts) > 0 { - if _, ok := inverseDsts[src]; ok { - merr = multierror.Append(merr, mkErr(src, dst)) - } - } - seen[src][dst] = struct{}{} - } - } - - return merr -} - -func (m *Manager) CalculateDependencies(registrations []resource.Registration) Dependencies { - typeToString := func(t *pbresource.Type) string { - return strings.ToLower(fmt.Sprintf("%s/%s/%s", t.Group, t.GroupVersion, t.Kind)) - } - - out := make(map[string][]string) - for _, r := range registrations { - out[typeToString(r.Type)] = nil - } - - for _, c := range m.controllers { - watches := make([]string, 0, len(c.watches)) - for _, w := range c.watches { - watches = append(watches, typeToString(w.watchedType)) - } - - out[typeToString(c.managedType)] = watches - } - - return out -} - -func (deps Dependencies) ToMermaid() string { - depStrings := make([]string, 0, len(deps)) - - for src, dsts := range deps { - if len(dsts) == 0 { - depStrings = append(depStrings, fmt.Sprintf(" %s", src)) - continue - } - - for _, dst := range dsts { - depStrings = append(depStrings, fmt.Sprintf(" %s --> %s", src, dst)) - } - } - - sort.Slice(depStrings, func(a, b int) bool { - return depStrings[a] < depStrings[b] - }) - out := "flowchart TD\n" + strings.Join(depStrings, "\n") - - return out -} diff --git a/internal/controller/dependencies_test.go b/internal/controller/dependencies_test.go deleted file mode 100644 index 18db58a2853ae..0000000000000 --- a/internal/controller/dependencies_test.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controller - -import ( - "testing" - - "github.com/hashicorp/consul/internal/testing/golden" - "github.com/stretchr/testify/require" -) - -func TestDependenciesGolden(t *testing.T) { - deps := Dependencies{ - "t1": []string{"t2", "t3"}, - "t2": []string{"t4"}, - "t4": []string{"t1"}, - } - mermaid := deps.ToMermaid() - expected := golden.Get(t, mermaid, "dependencies.golden") - require.Equal(t, expected, mermaid) -} - -func TestValidateDependencies(t *testing.T) { - type testCase struct { - dependencies Dependencies - expectErr string - } - - run := func(t *testing.T, tc testCase) { - err := tc.dependencies.validate() - if len(tc.expectErr) > 0 { - require.Contains(t, err.Error(), tc.expectErr) - } else { - require.NoError(t, err) - } - - } - - cases := map[string]testCase{ - "empty": { - dependencies: nil, - }, - "no circular dependencies": { - dependencies: Dependencies{ - "t1": []string{"t2", "t3"}, - "t2": []string{"t3"}, - "t3": []string{"t4"}, - "t4": nil, - }, - }, - "with circular dependency": { - dependencies: Dependencies{ - "t1": []string{"t2", "t3"}, - "t2": []string{"t1"}, - }, - expectErr: `circular dependency between "t1" and "t2"`, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/controller/manager.go b/internal/controller/manager.go index 2e46b21400837..1e7e910210616 100644 --- a/internal/controller/manager.go +++ b/internal/controller/manager.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/go-hclog" + "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -67,7 +68,7 @@ func (m *Manager) Run(ctx context.Context) { for _, desc := range m.controllers { logger := desc.logger if logger == nil { - logger = m.logger.With("managed_type", desc.managedType.Kind) + logger = m.logger.With("managed_type", resource.ToGVK(desc.managedType)) } runner := &controllerRunner{ diff --git a/internal/controller/testdata/dependencies.golden b/internal/controller/testdata/dependencies.golden deleted file mode 100644 index f0ff372a1634f..0000000000000 --- a/internal/controller/testdata/dependencies.golden +++ /dev/null @@ -1,5 +0,0 @@ -flowchart TD - t1 --> t2 - t1 --> t3 - t2 --> t4 - t4 --> t1 \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go index c078c3273e439..aea4360b83108 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go @@ -248,7 +248,7 @@ func (b *Builder) buildDestination( panic(fmt.Sprintf("it should not be possible to have a tcp protocol here: %v", effectiveProtocol)) } - rb := lb.addL7Router(routeName, statPrefix, effectiveProtocol) + rb := lb.addL7Router(routeName, "", effectiveProtocol) if destination.Explicit == nil { rb.addIPAndPortMatch(destination.VirtualIPs, virtualPortNumber) } @@ -290,6 +290,7 @@ func (b *Builder) buildDestination( clusterName := fmt.Sprintf("%s.%s", portName, sni) egName := "" + if details.FailoverConfig != nil { egName = fmt.Sprintf("%s%d~%s", xdscommon.FailoverClusterNamePrefix, 0, clusterName) } @@ -372,7 +373,7 @@ func (b *ListenerBuilder) addL4RouterForDirect(clusterName, statPrefix string) * router := &pbproxystate.Router{} if statPrefix == "" { - statPrefix = fmt.Sprintf("upstream.%s", clusterName) + statPrefix = "upstream." } router.Destination = &pbproxystate.Router_L4{ diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go index 7c4ff8df04a3b..33dcab7155228 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go @@ -28,7 +28,7 @@ func TestBuildLocalApp(t *testing.T) { ctp *pbauth.ComputedTrafficPermissions defaultAllow bool }{ - "source/single-workload-address-without-ports": { + "source/l4-single-workload-address-without-ports": { workload: &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ { @@ -36,15 +36,12 @@ func TestBuildLocalApp(t *testing.T) { }, }, Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "http": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "http2": {Port: 8082, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - "grpc": {Port: 8083, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, + "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, + "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, }, }, - "source/multiple-workload-addresses-without-ports": { + "source/l4-multiple-workload-addresses-without-ports": { workload: &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ { @@ -55,32 +52,26 @@ func TestBuildLocalApp(t *testing.T) { }, }, Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "http": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "http2": {Port: 8082, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - "grpc": {Port: 8083, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, + "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, + "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, }, }, - "source/multiple-workload-addresses-with-specific-ports": { + "source/l4-multiple-workload-addresses-with-specific-ports": { workload: &pbcatalog.Workload{ Addresses: []*pbcatalog.WorkloadAddress{ { Host: "127.0.0.1", - Ports: []string{"tcp", "grpc", "mesh"}, + Ports: []string{"port1"}, }, { Host: "10.0.0.2", - Ports: []string{"http", "http2", "mesh"}, + Ports: []string{"port2"}, }, }, Ports: map[string]*pbcatalog.WorkloadPort{ - "tcp": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, - "http": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, - "http2": {Port: 8082, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP2}, - "grpc": {Port: 8083, Protocol: pbcatalog.Protocol_PROTOCOL_GRPC}, - "mesh": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, + "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, + "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, }, }, ctp: &pbauth.ComputedTrafficPermissions{ @@ -102,27 +93,13 @@ func TestBuildLocalApp(t *testing.T) { for name, c := range cases { t.Run(name, func(t *testing.T) { - proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, nil). - BuildLocalApp(c.workload, nil). + proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", c.defaultAllow, nil). + BuildLocalApp(c.workload, c.ctp). Build() - - // sort routers because of test flakes where order was flip flopping. - actualRouters := proxyTmpl.ProxyState.Listeners[0].Routers - sort.Slice(actualRouters, func(i, j int) bool { - return actualRouters[i].String() < actualRouters[j].String() - }) - actual := protoToJSON(t, proxyTmpl) - expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+".golden")) + expected := golden.Get(t, actual, name+".golden") - // sort routers on listener from golden file - expectedRouters := expected.ProxyState.Listeners[0].Routers - sort.Slice(expectedRouters, func(i, j int) bool { - return expectedRouters[i].String() < expectedRouters[j].String() - }) - - // convert back to json after sorting so that test output does not contain extraneous fields. - require.Equal(t, protoToJSON(t, expected), protoToJSON(t, proxyTmpl)) + require.JSONEq(t, expected, actual) }) } } diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination.golden index cbd28e7a70a44..ca69db7dfcb0d 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/mixed-multi-destination.golden @@ -234,7 +234,7 @@ "route": { "name": "default/local/default/api-1:http:1.1.1.1:1234" }, - "statPrefix": "upstream.http.api-1.default.default.dc1" + "statPrefix": "upstream." } } ] diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden index 94e8e1c21577d..3192629710d92 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden @@ -1,8 +1,8 @@ { "proxyState": { "clusters": { - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -11,7 +11,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~http" + "consul~tcp2" ], "outboundMesh": { "identityKey": "test-identity", @@ -26,11 +26,11 @@ } } }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" + "name": "tcp2.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, - "http.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app2.default.dc1.internal.foo.consul", + "tcp2.api-app2.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app2.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -39,7 +39,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~http" + "consul~tcp2" ], "outboundMesh": { "identityKey": "test-identity", @@ -54,22 +54,11 @@ } } }, - "name": "http.api-app2.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", + "name": "tcp2.api-app2.default.dc1.internal.foo.consul", "protocol": "PROTOCOL_TCP" }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", + "http.api-app.default.dc1.internal.foo.consul": { + "altStatName": "http.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -78,7 +67,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp" + "consul~http" ], "outboundMesh": { "identityKey": "test-identity", @@ -93,11 +82,11 @@ } } }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_TCP" + "name": "http.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" }, - "tcp.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app2.default.dc1.internal.foo.consul", + "http.api-app2.default.dc1.internal.foo.consul": { + "altStatName": "http.api-app2.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -106,7 +95,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp" + "consul~http" ], "outboundMesh": { "identityKey": "test-identity", @@ -121,11 +110,22 @@ } } }, - "name": "tcp.api-app2.default.dc1.internal.foo.consul", + "name": "http.api-app2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" + }, + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", "protocol": "PROTOCOL_TCP" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -134,7 +134,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp2" + "consul~tcp" ], "outboundMesh": { "identityKey": "test-identity", @@ -149,11 +149,11 @@ } } }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", + "name": "tcp.api-app.default.dc1.internal.foo.consul", "protocol": "PROTOCOL_TCP" }, - "tcp2.api-app2.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app2.default.dc1.internal.foo.consul", + "tcp.api-app2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app2.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -162,7 +162,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp2" + "consul~tcp" ], "outboundMesh": { "identityKey": "test-identity", @@ -177,7 +177,7 @@ } } }, - "name": "tcp2.api-app2.default.dc1.internal.foo.consul", + "name": "tcp.api-app2.default.dc1.internal.foo.consul", "protocol": "PROTOCOL_TCP" } }, @@ -257,7 +257,7 @@ "route": { "name": "default/local/default/api-app:http" }, - "statPrefix": "upstream.http.api-app.default.default.dc1" + "statPrefix": "upstream." }, "match": { "destinationPort": 8080, @@ -274,7 +274,7 @@ "route": { "name": "default/local/default/api-app2:http" }, - "statPrefix": "upstream.http.api-app2.default.default.dc1" + "statPrefix": "upstream." }, "match": { "destinationPort": 8080, @@ -383,7 +383,7 @@ } }, "requiredEndpoints": { - "http.api-app.default.dc1.internal.foo.consul": { + "tcp2.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { @@ -399,7 +399,7 @@ }, "port": "mesh" }, - "http.api-app2.default.dc1.internal.foo.consul": { + "tcp2.api-app2.default.dc1.internal.foo.consul": { "id": { "name": "api-app2", "tenancy": { @@ -415,7 +415,7 @@ }, "port": "mesh" }, - "tcp.api-app.default.dc1.internal.foo.consul": { + "http.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { @@ -431,7 +431,7 @@ }, "port": "mesh" }, - "tcp.api-app2.default.dc1.internal.foo.consul": { + "http.api-app2.default.dc1.internal.foo.consul": { "id": { "name": "api-app2", "tenancy": { @@ -447,7 +447,7 @@ }, "port": "mesh" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { + "tcp.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { @@ -463,7 +463,7 @@ }, "port": "mesh" }, - "tcp2.api-app2.default.dc1.internal.foo.consul": { + "tcp.api-app2.default.dc1.internal.foo.consul": { "id": { "name": "api-app2", "tenancy": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden index 479a4e7aefd2f..2ab840e3da9bd 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden @@ -1,8 +1,8 @@ { "proxyState": { "clusters": { - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -11,7 +11,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~http" + "consul~tcp2" ], "outboundMesh": { "identityKey": "test-identity", @@ -26,22 +26,11 @@ } } }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", + "name": "tcp2.api-app.default.dc1.internal.foo.consul", "protocol": "PROTOCOL_TCP" }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", + "http.api-app.default.dc1.internal.foo.consul": { + "altStatName": "http.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -50,7 +39,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp" + "consul~http" ], "outboundMesh": { "identityKey": "test-identity", @@ -65,11 +54,22 @@ } } }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", + "name": "http.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" + }, + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", "protocol": "PROTOCOL_TCP" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -78,7 +78,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp2" + "consul~tcp" ], "outboundMesh": { "identityKey": "test-identity", @@ -93,7 +93,7 @@ } } }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", + "name": "tcp.api-app.default.dc1.internal.foo.consul", "protocol": "PROTOCOL_TCP" } }, @@ -152,7 +152,7 @@ "route": { "name": "default/local/default/api-app:http" }, - "statPrefix": "upstream.http.api-app.default.default.dc1" + "statPrefix": "upstream." }, "match": { "destinationPort": 8080, @@ -212,7 +212,7 @@ } }, "requiredEndpoints": { - "http.api-app.default.dc1.internal.foo.consul": { + "tcp2.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { @@ -228,7 +228,7 @@ }, "port": "mesh" }, - "tcp.api-app.default.dc1.internal.foo.consul": { + "http.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { @@ -244,7 +244,7 @@ }, "port": "mesh" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { + "tcp.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden index 479a4e7aefd2f..2ab840e3da9bd 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -1,8 +1,8 @@ { "proxyState": { "clusters": { - "http.api-app.default.dc1.internal.foo.consul": { - "altStatName": "http.api-app.default.dc1.internal.foo.consul", + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -11,7 +11,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~http" + "consul~tcp2" ], "outboundMesh": { "identityKey": "test-identity", @@ -26,22 +26,11 @@ } } }, - "name": "http.api-app.default.dc1.internal.foo.consul", - "protocol": "PROTOCOL_HTTP" - }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination", + "name": "tcp2.api-app.default.dc1.internal.foo.consul", "protocol": "PROTOCOL_TCP" }, - "tcp.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", + "http.api-app.default.dc1.internal.foo.consul": { + "altStatName": "http.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -50,7 +39,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp" + "consul~http" ], "outboundMesh": { "identityKey": "test-identity", @@ -65,11 +54,22 @@ } } }, - "name": "tcp.api-app.default.dc1.internal.foo.consul", + "name": "http.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" + }, + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", "protocol": "PROTOCOL_TCP" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -78,7 +78,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp2" + "consul~tcp" ], "outboundMesh": { "identityKey": "test-identity", @@ -93,7 +93,7 @@ } } }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul", + "name": "tcp.api-app.default.dc1.internal.foo.consul", "protocol": "PROTOCOL_TCP" } }, @@ -152,7 +152,7 @@ "route": { "name": "default/local/default/api-app:http" }, - "statPrefix": "upstream.http.api-app.default.default.dc1" + "statPrefix": "upstream." }, "match": { "destinationPort": 8080, @@ -212,7 +212,7 @@ } }, "requiredEndpoints": { - "http.api-app.default.dc1.internal.foo.consul": { + "tcp2.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { @@ -228,7 +228,7 @@ }, "port": "mesh" }, - "tcp.api-app.default.dc1.internal.foo.consul": { + "http.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { @@ -244,7 +244,7 @@ }, "port": "mesh" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { + "tcp.api-app.default.dc1.internal.foo.consul": { "id": { "name": "api-app", "tenancy": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 0000000000000..95ee222f3d26d --- /dev/null +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,101 @@ +{ + "proxyState": { + "clusters": { + "local_app:port1": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "auth", + "groupVersion": "v2beta1", + "kind": "WorkloadIdentity" + } + }, + "listeners": [ + { + "capabilities": [ + "CAPABILITY_L4_TLS_INSPECTION" + ], + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.2", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:port1" + }, + "statPrefix": "public_listener", + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + } + ] + } + ] + }, + "requiredLeafCertificates": { + "test-identity": { + "name": "test-identity", + "namespace": "default", + "partition": "default" + } + }, + "requiredTrustBundles": { + "local": { + "peer": "local" + } + } +} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 0000000000000..0cb52d9921557 --- /dev/null +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,89 @@ +{ + "proxyState": { + "clusters": { + "local_app:port1": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "auth", + "groupVersion": "v2beta1", + "kind": "WorkloadIdentity" + } + }, + "listeners": [ + { + "capabilities": [ + "CAPABILITY_L4_TLS_INSPECTION" + ], + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:port1" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + } + ] + } + ] + }, + "requiredLeafCertificates": { + "test-identity": { + "name": "test-identity", + "namespace": "default", + "partition": "default" + } + }, + "requiredTrustBundles": { + "local": { + "peer": "local" + } + } +} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-single-workload-address-without-ports.golden new file mode 100644 index 0000000000000..0cb52d9921557 --- /dev/null +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l4-single-workload-address-without-ports.golden @@ -0,0 +1,89 @@ +{ + "proxyState": { + "clusters": { + "local_app:port1": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "auth", + "groupVersion": "v2beta1", + "kind": "WorkloadIdentity" + } + }, + "listeners": [ + { + "capabilities": [ + "CAPABILITY_L4_TLS_INSPECTION" + ], + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:port1" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + } + ] + } + ] + }, + "requiredLeafCertificates": { + "test-identity": { + "name": "test-identity", + "namespace": "default", + "partition": "default" + } + }, + "requiredTrustBundles": { + "local": { + "peer": "local" + } + } +} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index 70d0232467f1f..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,291 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:grpc": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc", - "protocol": "PROTOCOL_GRPC" - }, - "local_app:http": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:http2": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http2", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:tcp": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:tcp", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:grpc": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8083 - } - } - ] - }, - "local_app:http": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8081 - } - } - ] - }, - "local_app:http2": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8082 - } - } - ] - }, - "local_app:tcp": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:http" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:http2" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http2" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:tcp" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~tcp" - ] - } - } - ] - } - ], - "routes": { - "public_listener:grpc": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http2": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http2", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http2" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-without-ports.golden deleted file mode 100644 index b86daa2817148..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,291 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:grpc": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc", - "protocol": "PROTOCOL_GRPC" - }, - "local_app:http": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:http2": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http2", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:tcp": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:tcp", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:grpc": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8083 - } - } - ] - }, - "local_app:http": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8081 - } - } - ] - }, - "local_app:http2": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8082 - } - } - ] - }, - "local_app:tcp": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:http" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:http2" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http2" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:tcp" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~tcp" - ] - } - } - ] - } - ], - "routes": { - "public_listener:grpc": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http2": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http2", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http2" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/single-workload-address-without-ports.golden deleted file mode 100644 index b86daa2817148..0000000000000 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/single-workload-address-without-ports.golden +++ /dev/null @@ -1,291 +0,0 @@ -{ - "proxyState": { - "clusters": { - "local_app:grpc": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc", - "protocol": "PROTOCOL_GRPC" - }, - "local_app:http": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:http2": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http2", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:tcp": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:tcp", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:grpc": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8083 - } - } - ] - }, - "local_app:http": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8081 - } - } - ] - }, - "local_app:http2": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8082 - } - } - ] - }, - "local_app:tcp": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:http" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:http2" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http2" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:tcp" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~tcp" - ] - } - } - ] - } - ], - "routes": { - "public_listener:grpc": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http2": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http2", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http2" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - } - }, - "requiredLeafCertificates": { - "test-identity": { - "name": "test-identity", - "namespace": "default", - "partition": "default" - } - }, - "requiredTrustBundles": { - "local": { - "peer": "local" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/controller_test.go b/internal/mesh/internal/controllers/xds/controller_test.go index 15c4536e55826..e1dd0ebb61719 100644 --- a/internal/mesh/internal/controllers/xds/controller_test.go +++ b/internal/mesh/internal/controllers/xds/controller_test.go @@ -241,10 +241,7 @@ func (suite *xdsControllerTestSuite) TestReconcile_ReadEndpointError() { require.Error(suite.T(), err) // Assert on the status reflecting endpoint couldn't be read. - suite.client.RequireStatusCondition(suite.T(), fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedErrorReadingEndpoints( - status.KeyFromID(badID), - "rpc error: code = InvalidArgument desc = id.name invalid: a resource name must consist of lower case alphanumeric characters or '-', must start and end with an alphanumeric character and be less than 64 characters, got: \"\"", - )) + suite.client.RequireStatusCondition(suite.T(), fooProxyStateTemplate.Id, ControllerName, status.ConditionRejectedErrorReadingEndpoints(status.KeyFromID(badID), "rpc error: code = InvalidArgument desc = id.name is required")) } // This test is a happy path creation test to make sure pbproxystate.Endpoints are created in the computed @@ -1032,17 +1029,16 @@ func (suite *xdsControllerTestSuite) TestReconcile_SidecarProxyGoldenFileInputs( "destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy", //sources - please add in alphabetical order + "source/l4-multiple-workload-addresses-with-specific-ports", + "source/l4-multiple-workload-addresses-without-ports", + "source/l4-single-workload-address-without-ports", "source/l7-expose-paths", "source/local-and-inbound-connections", - "source/multiple-workload-addresses-with-specific-ports", - "source/multiple-workload-addresses-without-ports", "source/multiport-l4-multiple-workload-addresses-with-specific-ports", "source/multiport-l4-multiple-workload-addresses-without-ports", "source/multiport-l4-workload-with-only-mesh-port", "source/multiport-l7-multiple-workload-addresses-with-specific-ports", "source/multiport-l7-multiple-workload-addresses-without-ports", - "source/multiport-l7-multiple-workload-addresses-without-ports", - "source/single-workload-address-without-ports", } for _, name := range cases { diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden b/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden index 3acd9869e51dc..16b1841296ed8 100644 --- a/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden +++ b/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden @@ -285,7 +285,7 @@ "route": { "name": "default/local/default/api-1:http:1.1.1.1:1234" }, - "statPrefix": "upstream.http.api-1.default.default.dc1" + "statPrefix": "upstream." } } ] @@ -377,4 +377,4 @@ "trustDomain": "some-trust-domain" } } -} \ No newline at end of file +} diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden index 0158f07aa2c58..7ac1ec80710b5 100644 --- a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden +++ b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden @@ -330,7 +330,7 @@ "route": { "name": "default/local/default/api-app:http" }, - "statPrefix": "upstream.http.api-app.default.default.dc1" + "statPrefix": "upstream." }, "match": { "destinationPort": 8080, @@ -347,7 +347,7 @@ "route": { "name": "default/local/default/api-app2:http" }, - "statPrefix": "upstream.http.api-app2.default.default.dc1" + "statPrefix": "upstream." }, "match": { "destinationPort": 8080, @@ -463,4 +463,4 @@ "trustDomain": "some-trust-domain" } } -} \ No newline at end of file +} diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden index 3c9d62fb4ea17..8f5e73c92ee52 100644 --- a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden +++ b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden @@ -192,7 +192,7 @@ "route": { "name": "default/local/default/api-app:http" }, - "statPrefix": "upstream.http.api-app.default.default.dc1" + "statPrefix": "upstream." }, "match": { "destinationPort": 8080, @@ -259,4 +259,4 @@ "trustDomain": "some-trust-domain" } } -} \ No newline at end of file +} diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden index 3c9d62fb4ea17..8f5e73c92ee52 100644 --- a/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden +++ b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -192,7 +192,7 @@ "route": { "name": "default/local/default/api-app:http" }, - "statPrefix": "upstream.http.api-app.default.default.dc1" + "statPrefix": "upstream." }, "match": { "destinationPort": 8080, @@ -259,4 +259,4 @@ "trustDomain": "some-trust-domain" } } -} \ No newline at end of file +} diff --git a/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 0000000000000..c88a05495613c --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,102 @@ +{ + "clusters": { + "local_app:port1": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "auth", + "groupVersion": "v2beta1", + "kind": "WorkloadIdentity" + } + }, + "leafCertificates": { + "test-identity": { + "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", + "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + } + }, + "listeners": [ + { + "capabilities": [ + "CAPABILITY_L4_TLS_INSPECTION" + ], + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.2", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:port1" + }, + "statPrefix": "public_listener", + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + } + ] + } + ], + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + } +} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 0000000000000..439c536fdc3bb --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,90 @@ +{ + "clusters": { + "local_app:port1": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "auth", + "groupVersion": "v2beta1", + "kind": "WorkloadIdentity" + } + }, + "leafCertificates": { + "test-identity": { + "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", + "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + } + }, + "listeners": [ + { + "capabilities": [ + "CAPABILITY_L4_TLS_INSPECTION" + ], + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:port1" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + } + ] + } + ], + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + } +} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/l4-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/l4-single-workload-address-without-ports.golden new file mode 100644 index 0000000000000..439c536fdc3bb --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/l4-single-workload-address-without-ports.golden @@ -0,0 +1,90 @@ +{ + "clusters": { + "local_app:port1": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "auth", + "groupVersion": "v2beta1", + "kind": "WorkloadIdentity" + } + }, + "leafCertificates": { + "test-identity": { + "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", + "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" + } + }, + "listeners": [ + { + "capabilities": [ + "CAPABILITY_L4_TLS_INSPECTION" + ], + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:port1" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + } + ] + } + ], + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + } +} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports.golden deleted file mode 100644 index b67d034c7e345..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports.golden +++ /dev/null @@ -1,292 +0,0 @@ -{ - "clusters": { - "local_app:grpc": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc", - "protocol": "PROTOCOL_GRPC" - }, - "local_app:http": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:http2": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http2", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:tcp": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:tcp", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:grpc": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8083 - } - } - ] - }, - "local_app:http": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8081 - } - } - ] - }, - "local_app:http2": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8082 - } - } - ] - }, - "local_app:tcp": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:http" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:http2" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http2" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:tcp" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~tcp" - ] - } - } - ] - } - ], - "routes": { - "public_listener:grpc": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http2": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http2", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http2" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-without-ports.golden deleted file mode 100644 index 8b04918948654..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-without-ports.golden +++ /dev/null @@ -1,292 +0,0 @@ -{ - "clusters": { - "local_app:grpc": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc", - "protocol": "PROTOCOL_GRPC" - }, - "local_app:http": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:http2": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http2", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:tcp": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:tcp", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:grpc": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8083 - } - } - ] - }, - "local_app:http": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8081 - } - } - ] - }, - "local_app:http2": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8082 - } - } - ] - }, - "local_app:tcp": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:http" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:http2" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http2" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:tcp" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~tcp" - ] - } - } - ] - } - ], - "routes": { - "public_listener:grpc": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http2": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http2", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http2" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/single-workload-address-without-ports.golden deleted file mode 100644 index 8b04918948654..0000000000000 --- a/internal/mesh/internal/controllers/xds/testdata/source/single-workload-address-without-ports.golden +++ /dev/null @@ -1,292 +0,0 @@ -{ - "clusters": { - "local_app:grpc": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:grpc", - "protocol": "PROTOCOL_GRPC" - }, - "local_app:http": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http", - "protocol": "PROTOCOL_HTTP" - }, - "local_app:http2": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:http2", - "protocol": "PROTOCOL_HTTP2" - }, - "local_app:tcp": { - "endpointGroup": { - "static": {} - }, - "name": "local_app:tcp", - "protocol": "PROTOCOL_TCP" - } - }, - "endpoints": { - "local_app:grpc": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8083 - } - } - ] - }, - "local_app:http": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8081 - } - } - ] - }, - "local_app:http2": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8082 - } - } - ] - }, - "local_app:tcp": { - "endpoints": [ - { - "hostPort": { - "host": "127.0.0.1", - "port": 8080 - } - } - ] - } - }, - "identity": { - "name": "test-identity", - "tenancy": { - "namespace": "default", - "partition": "default", - "peerName": "local" - }, - "type": { - "group": "auth", - "groupVersion": "v2beta1", - "kind": "WorkloadIdentity" - } - }, - "leafCertificates": { - "test-identity": { - "cert": "-----BEGIN CERTIFICATE-----\nMIICDjCCAbWgAwIBAgIBAjAKBggqhkjOPQQDAjAUMRIwEAYDVQQDEwlUZXN0IENB\nIDEwHhcNMjMxMDE2MTYxMzI5WhcNMjMxMDE2MTYyMzI5WjAAMFkwEwYHKoZIzj0C\nAQYIKoZIzj0DAQcDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9\nta/bGT+5orZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJaOCAQowggEGMA4GA1UdDwEB\n/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwDAYDVR0TAQH/\nBAIwADApBgNVHQ4EIgQg3ogXVz9cqaK2B6xdiJYMa5NtT0KkYv7BA2dR7h9EcwUw\nKwYDVR0jBCQwIoAgq+C1mPlPoGa4lt7sSft1goN5qPGyBIB/3mUHJZKSFY8wbwYD\nVR0RAQH/BGUwY4Zhc3BpZmZlOi8vMTExMTExMTEtMjIyMi0zMzMzLTQ0NDQtNTU1\nNTU1NTU1NTU1LmNvbnN1bC9hcC9kZWZhdWx0L25zL2RlZmF1bHQvaWRlbnRpdHkv\ndGVzdC1pZGVudGl0eTAKBggqhkjOPQQDAgNHADBEAiB6L+t5bzRrBPhiQYNeA7fF\nUCuLWrdjW4Xbv3SLg0IKMgIgfRC5hEx+DqzQxTCP4sexX3hVWMjKoWmHdwiUcg+K\n/IE=\n-----END CERTIFICATE-----\n", - "key": "-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIFIFkTIL1iUV4O/RpveVHzHs7ZzhSkvYIzbdXDttz9EooAoGCCqGSM49\nAwEHoUQDQgAErErAIosDPheZQGbxFQ4hYC/e9Fi4MG9z/zjfCnCq/oK9ta/bGT+5\norZqTmdN/ICsKQDhykxZ2u/Xr6845zhcJQ==\n-----END EC PRIVATE KEY-----\n" - } - }, - "listeners": [ - { - "capabilities": [ - "CAPABILITY_L4_TLS_INSPECTION" - ], - "direction": "DIRECTION_INBOUND", - "hostPort": { - "host": "10.0.0.1", - "port": 20000 - }, - "name": "public_listener", - "routers": [ - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_GRPC", - "route": { - "name": "public_listener:grpc" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~grpc" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "route": { - "name": "public_listener:http" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l7": { - "protocol": "L7_PROTOCOL_HTTP2", - "route": { - "name": "public_listener:http2" - }, - "statPrefix": "public_listener", - "staticRoute": true, - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~http2" - ] - } - }, - { - "inboundTls": { - "inboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "trustBundlePeerNameKeys": [ - "local" - ] - } - } - }, - "l4": { - "cluster": { - "name": "local_app:tcp" - }, - "statPrefix": "public_listener", - "trafficPermissions": {} - }, - "match": { - "alpnProtocols": [ - "consul~tcp" - ] - } - } - ] - } - ], - "routes": { - "public_listener:grpc": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:grpc", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:grpc" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - }, - "public_listener:http2": { - "virtualHosts": [ - { - "domains": [ - "*" - ], - "name": "public_listener:http2", - "routeRules": [ - { - "destination": { - "cluster": { - "name": "local_app:http2" - } - }, - "match": { - "pathMatch": { - "prefix": "/" - } - } - } - ] - } - ] - } - }, - "trustBundles": { - "local": { - "roots": [ - "some-root", - "some-other-root" - ], - "trustDomain": "some-trust-domain" - } - } -} \ No newline at end of file diff --git a/internal/mesh/internal/types/computed_routes.go b/internal/mesh/internal/types/computed_routes.go index b572c01fc3764..1f66cc97ac211 100644 --- a/internal/mesh/internal/types/computed_routes.go +++ b/internal/mesh/internal/types/computed_routes.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) const ( @@ -29,12 +30,16 @@ func RegisterComputedRoutes(r resource.Registry) { }) } -var ValidateComputedRoutes = resource.DecodeAndValidate(validateComputedRoutes) +func ValidateComputedRoutes(res *pbresource.Resource) error { + var config pbmesh.ComputedRoutes + + if err := res.Data.UnmarshalTo(&config); err != nil { + return resource.NewErrDataParse(&config, err) + } -func validateComputedRoutes(res *DecodedComputedRoutes) error { var merr error - if len(res.Data.PortedConfigs) == 0 { + if len(config.PortedConfigs) == 0 { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "ported_configs", Wrapped: resource.ErrEmpty, @@ -43,7 +48,7 @@ func validateComputedRoutes(res *DecodedComputedRoutes) error { // TODO(rb): do more elaborate validation - for port, pmc := range res.Data.PortedConfigs { + for port, pmc := range config.PortedConfigs { wrapErr := func(err error) error { return resource.ErrInvalidMapValue{ Map: "ported_configs", diff --git a/internal/mesh/internal/types/decoded.go b/internal/mesh/internal/types/decoded.go index be4836c066ff7..ee1244fdcb1bc 100644 --- a/internal/mesh/internal/types/decoded.go +++ b/internal/mesh/internal/types/decoded.go @@ -15,7 +15,6 @@ type ( DecodedGRPCRoute = resource.DecodedResource[*pbmesh.GRPCRoute] DecodedTCPRoute = resource.DecodedResource[*pbmesh.TCPRoute] DecodedDestinationPolicy = resource.DecodedResource[*pbmesh.DestinationPolicy] - DecodedDestinationsConfiguration = resource.DecodedResource[*pbmesh.DestinationsConfiguration] DecodedComputedRoutes = resource.DecodedResource[*pbmesh.ComputedRoutes] DecodedComputedTrafficPermissions = resource.DecodedResource[*pbauth.ComputedTrafficPermissions] DecodedFailoverPolicy = resource.DecodedResource[*pbcatalog.FailoverPolicy] diff --git a/internal/mesh/internal/types/destination_policy.go b/internal/mesh/internal/types/destination_policy.go index 4fe3062367cf5..68b37345baf3e 100644 --- a/internal/mesh/internal/types/destination_policy.go +++ b/internal/mesh/internal/types/destination_policy.go @@ -29,19 +29,23 @@ func RegisterDestinationPolicy(r resource.Registry) { }) } -var ValidateDestinationPolicy = resource.DecodeAndValidate(validateDestinationPolicy) +func ValidateDestinationPolicy(res *pbresource.Resource) error { + var policy pbmesh.DestinationPolicy + + if err := res.Data.UnmarshalTo(&policy); err != nil { + return resource.NewErrDataParse(&policy, err) + } -func validateDestinationPolicy(res *DecodedDestinationPolicy) error { var merr error - if len(res.Data.PortConfigs) == 0 { + if len(policy.PortConfigs) == 0 { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "port_configs", Wrapped: resource.ErrEmpty, }) } - for port, pc := range res.Data.PortConfigs { + for port, pc := range policy.PortConfigs { wrapErr := func(err error) error { return resource.ErrInvalidMapValue{ Map: "port_configs", diff --git a/internal/mesh/internal/types/destinations.go b/internal/mesh/internal/types/destinations.go index 7de3011e3ef0a..34287e627ab71 100644 --- a/internal/mesh/internal/types/destinations.go +++ b/internal/mesh/internal/types/destinations.go @@ -26,12 +26,16 @@ func RegisterDestinations(r resource.Registry) { }) } -var MutateDestinations = resource.DecodeAndMutate(mutateDestinations) +func MutateDestinations(res *pbresource.Resource) error { + var destinations pbmesh.Destinations + + if err := res.Data.UnmarshalTo(&destinations); err != nil { + return resource.NewErrDataParse(&destinations, err) + } -func mutateDestinations(res *DecodedDestinations) (bool, error) { changed := false - for _, dest := range res.Data.Destinations { + for _, dest := range destinations.Destinations { if dest.DestinationRef == nil { continue // skip; let the validation hook error out instead } @@ -52,33 +56,41 @@ func mutateDestinations(res *DecodedDestinations) (bool, error) { } } - return changed, nil + if !changed { + return nil + } + + return res.Data.MarshalFrom(&destinations) } func isLocalPeer(p string) bool { return p == "local" || p == "" } -var ValidateDestinations = resource.DecodeAndValidate(validateDestinations) +func ValidateDestinations(res *pbresource.Resource) error { + var destinations pbmesh.Destinations + + if err := res.Data.UnmarshalTo(&destinations); err != nil { + return resource.NewErrDataParse(&destinations, err) + } -func validateDestinations(res *DecodedDestinations) error { var merr error - if selErr := catalog.ValidateSelector(res.Data.Workloads, false); selErr != nil { + if selErr := catalog.ValidateSelector(destinations.Workloads, false); selErr != nil { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, }) } - if res.Data.GetPqDestinations() != nil { + if destinations.GetPqDestinations() != nil { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "pq_destinations", Wrapped: resource.ErrUnsupported, }) } - for i, dest := range res.Data.Destinations { + for i, dest := range destinations.Destinations { wrapDestErr := func(err error) error { return resource.ErrInvalidListElement{ Name: "destinations", diff --git a/internal/mesh/internal/types/destinations_configuration.go b/internal/mesh/internal/types/destinations_configuration.go index 7d46d93ed9993..fedbe40df48c1 100644 --- a/internal/mesh/internal/types/destinations_configuration.go +++ b/internal/mesh/internal/types/destinations_configuration.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) func RegisterDestinationsConfiguration(r resource.Registry) { @@ -22,13 +23,17 @@ func RegisterDestinationsConfiguration(r resource.Registry) { }) } -var ValidateDestinationsConfiguration = resource.DecodeAndValidate(validateDestinationsConfiguration) +func ValidateDestinationsConfiguration(res *pbresource.Resource) error { + var cfg pbmesh.DestinationsConfiguration + + if err := res.Data.UnmarshalTo(&cfg); err != nil { + return resource.NewErrDataParse(&cfg, err) + } -func validateDestinationsConfiguration(res *DecodedDestinationsConfiguration) error { var merr error // Validate the workload selector - if selErr := catalog.ValidateSelector(res.Data.Workloads, false); selErr != nil { + if selErr := catalog.ValidateSelector(cfg.Workloads, false); selErr != nil { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, diff --git a/internal/mesh/internal/types/grpc_route.go b/internal/mesh/internal/types/grpc_route.go index b861abccdc050..630e416e611c4 100644 --- a/internal/mesh/internal/types/grpc_route.go +++ b/internal/mesh/internal/types/grpc_route.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) func RegisterGRPCRoute(r resource.Registry) { @@ -24,16 +25,20 @@ func RegisterGRPCRoute(r resource.Registry) { }) } -var MutateGRPCRoute = resource.DecodeAndMutate(mutateGRPCRoute) +func MutateGRPCRoute(res *pbresource.Resource) error { + var route pbmesh.GRPCRoute + + if err := res.Data.UnmarshalTo(&route); err != nil { + return resource.NewErrDataParse(&route, err) + } -func mutateGRPCRoute(res *DecodedGRPCRoute) (bool, error) { changed := false - if mutateParentRefs(res.Id.Tenancy, res.Data.ParentRefs) { + if mutateParentRefs(res.Id.Tenancy, route.ParentRefs) { changed = true } - for _, rule := range res.Data.Rules { + for _, rule := range route.Rules { for _, backend := range rule.BackendRefs { if backend.BackendRef == nil || backend.BackendRef.Ref == nil { continue @@ -44,25 +49,33 @@ func mutateGRPCRoute(res *DecodedGRPCRoute) (bool, error) { } } - return changed, nil + if !changed { + return nil + } + + return res.Data.MarshalFrom(&route) } -var ValidateGRPCRoute = resource.DecodeAndValidate(validateGRPCRoute) +func ValidateGRPCRoute(res *pbresource.Resource) error { + var route pbmesh.GRPCRoute + + if err := res.Data.UnmarshalTo(&route); err != nil { + return resource.NewErrDataParse(&route, err) + } -func validateGRPCRoute(res *DecodedGRPCRoute) error { var merr error - if err := validateParentRefs(res.Id, res.Data.ParentRefs); err != nil { + if err := validateParentRefs(res.Id, route.ParentRefs); err != nil { merr = multierror.Append(merr, err) } - if len(res.Data.Hostnames) > 0 { + if len(route.Hostnames) > 0 { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "hostnames", Wrapped: errors.New("should not populate hostnames"), }) } - for i, rule := range res.Data.Rules { + for i, rule := range route.Rules { wrapRuleErr := func(err error) error { return resource.ErrInvalidListElement{ Name: "rules", diff --git a/internal/mesh/internal/types/http_route.go b/internal/mesh/internal/types/http_route.go index d32f55dc6cc82..0ac2dcbf5c8b0 100644 --- a/internal/mesh/internal/types/http_route.go +++ b/internal/mesh/internal/types/http_route.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) func RegisterHTTPRoute(r resource.Registry) { @@ -26,16 +27,20 @@ func RegisterHTTPRoute(r resource.Registry) { }) } -var MutateHTTPRoute = resource.DecodeAndMutate(mutateHTTPRoute) +func MutateHTTPRoute(res *pbresource.Resource) error { + var route pbmesh.HTTPRoute + + if err := res.Data.UnmarshalTo(&route); err != nil { + return resource.NewErrDataParse(&route, err) + } -func mutateHTTPRoute(res *DecodedHTTPRoute) (bool, error) { changed := false - if mutateParentRefs(res.Id.Tenancy, res.Data.ParentRefs) { + if mutateParentRefs(res.Id.Tenancy, route.ParentRefs) { changed = true } - for _, rule := range res.Data.Rules { + for _, rule := range route.Rules { for _, match := range rule.Matches { if match.Method != "" { norm := strings.ToUpper(match.Method) @@ -55,25 +60,33 @@ func mutateHTTPRoute(res *DecodedHTTPRoute) (bool, error) { } } - return changed, nil + if !changed { + return nil + } + + return res.Data.MarshalFrom(&route) } -var ValidateHTTPRoute = resource.DecodeAndValidate(validateHTTPRoute) +func ValidateHTTPRoute(res *pbresource.Resource) error { + var route pbmesh.HTTPRoute + + if err := res.Data.UnmarshalTo(&route); err != nil { + return resource.NewErrDataParse(&route, err) + } -func validateHTTPRoute(res *DecodedHTTPRoute) error { var merr error - if err := validateParentRefs(res.Id, res.Data.ParentRefs); err != nil { + if err := validateParentRefs(res.Id, route.ParentRefs); err != nil { merr = multierror.Append(merr, err) } - if len(res.Data.Hostnames) > 0 { + if len(route.Hostnames) > 0 { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "hostnames", Wrapped: errors.New("should not populate hostnames"), }) } - for i, rule := range res.Data.Rules { + for i, rule := range route.Rules { wrapRuleErr := func(err error) error { return resource.ErrInvalidListElement{ Name: "rules", diff --git a/internal/mesh/internal/types/proxy_configuration.go b/internal/mesh/internal/types/proxy_configuration.go index 9a4388a40f01d..081324d721675 100644 --- a/internal/mesh/internal/types/proxy_configuration.go +++ b/internal/mesh/internal/types/proxy_configuration.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/iptables" ) @@ -26,40 +27,52 @@ func RegisterProxyConfiguration(r resource.Registry) { }) } -var MutateProxyConfiguration = resource.DecodeAndMutate(mutateProxyConfiguration) +func MutateProxyConfiguration(res *pbresource.Resource) error { + var proxyCfg pbmesh.ProxyConfiguration + err := res.Data.UnmarshalTo(&proxyCfg) + if err != nil { + return resource.NewErrDataParse(&proxyCfg, err) + } -func mutateProxyConfiguration(res *DecodedProxyConfiguration) (bool, error) { changed := false // Default the tproxy outbound port. - if res.Data.IsTransparentProxy() { - if res.Data.GetDynamicConfig().GetTransparentProxy() == nil { - res.Data.DynamicConfig.TransparentProxy = &pbmesh.TransparentProxy{ + if proxyCfg.IsTransparentProxy() { + if proxyCfg.GetDynamicConfig().GetTransparentProxy() == nil { + proxyCfg.DynamicConfig.TransparentProxy = &pbmesh.TransparentProxy{ OutboundListenerPort: iptables.DefaultTProxyOutboundPort, } changed = true - } else if res.Data.GetDynamicConfig().GetTransparentProxy().OutboundListenerPort == 0 { - res.Data.DynamicConfig.TransparentProxy.OutboundListenerPort = iptables.DefaultTProxyOutboundPort + } else if proxyCfg.GetDynamicConfig().GetTransparentProxy().OutboundListenerPort == 0 { + proxyCfg.DynamicConfig.TransparentProxy.OutboundListenerPort = iptables.DefaultTProxyOutboundPort changed = true } } - return changed, nil + if !changed { + return nil + } + + return res.Data.MarshalFrom(&proxyCfg) } -var ValidateProxyConfiguration = resource.DecodeAndValidate(validateProxyConfiguration) +func ValidateProxyConfiguration(res *pbresource.Resource) error { + decodedProxyCfg, decodeErr := resource.Decode[*pbmesh.ProxyConfiguration](res) + if decodeErr != nil { + return resource.NewErrDataParse(decodedProxyCfg.GetData(), decodeErr) + } + proxyCfg := decodedProxyCfg.GetData() -func validateProxyConfiguration(res *DecodedProxyConfiguration) error { var err error - if selErr := catalog.ValidateSelector(res.Data.Workloads, false); selErr != nil { + if selErr := catalog.ValidateSelector(proxyCfg.Workloads, false); selErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, }) } - if res.Data.GetDynamicConfig() == nil && res.Data.GetBootstrapConfig() == nil { + if proxyCfg.GetDynamicConfig() == nil && proxyCfg.GetBootstrapConfig() == nil { err = multierror.Append(err, resource.ErrInvalidFields{ Names: []string{"dynamic_config", "bootstrap_config"}, Wrapped: errMissingProxyConfigData, @@ -67,14 +80,14 @@ func validateProxyConfiguration(res *DecodedProxyConfiguration) error { } // nolint:staticcheck - if res.Data.GetOpaqueConfig() != nil { + if proxyCfg.GetOpaqueConfig() != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "opaque_config", Wrapped: resource.ErrUnsupported, }) } - if dynamicCfgErr := validateDynamicProxyConfiguration(res.Data.GetDynamicConfig()); dynamicCfgErr != nil { + if dynamicCfgErr := validateDynamicProxyConfiguration(proxyCfg.GetDynamicConfig()); dynamicCfgErr != nil { err = multierror.Append(err, resource.ErrInvalidField{ Name: "dynamic_config", Wrapped: dynamicCfgErr, diff --git a/internal/mesh/internal/types/proxy_state_template.go b/internal/mesh/internal/types/proxy_state_template.go index 43d2148217e03..7db3dbaf55fd9 100644 --- a/internal/mesh/internal/types/proxy_state_template.go +++ b/internal/mesh/internal/types/proxy_state_template.go @@ -50,21 +50,25 @@ func RegisterProxyStateTemplate(r resource.Registry) { }) } -var ValidateProxyStateTemplate = resource.DecodeAndValidate(validateProxyStateTemplate) - -func validateProxyStateTemplate(res *DecodedProxyStateTemplate) error { +func ValidateProxyStateTemplate(res *pbresource.Resource) error { // TODO(v2): validate a lot more of this + var pst pbmesh.ProxyStateTemplate + + if err := res.Data.UnmarshalTo(&pst); err != nil { + return resource.NewErrDataParse(&pst, err) + } + var merr error - if res.Data.ProxyState != nil { + if pst.ProxyState != nil { wrapProxyStateErr := func(err error) error { return resource.ErrInvalidField{ Name: "proxy_state", Wrapped: err, } } - for name, cluster := range res.Data.ProxyState.Clusters { + for name, cluster := range pst.ProxyState.Clusters { if name == "" { merr = multierror.Append(merr, wrapProxyStateErr(resource.ErrInvalidMapKey{ Map: "clusters", diff --git a/internal/mesh/internal/types/tcp_route.go b/internal/mesh/internal/types/tcp_route.go index 02dd5aaa10fdd..c7470b14d55ae 100644 --- a/internal/mesh/internal/types/tcp_route.go +++ b/internal/mesh/internal/types/tcp_route.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) func RegisterTCPRoute(r resource.Registry) { @@ -23,16 +24,20 @@ func RegisterTCPRoute(r resource.Registry) { }) } -var MutateTCPRoute = resource.DecodeAndMutate(mutateTCPRoute) +func MutateTCPRoute(res *pbresource.Resource) error { + var route pbmesh.TCPRoute + + if err := res.Data.UnmarshalTo(&route); err != nil { + return resource.NewErrDataParse(&route, err) + } -func mutateTCPRoute(res *DecodedTCPRoute) (bool, error) { changed := false - if mutateParentRefs(res.Id.Tenancy, res.Data.ParentRefs) { + if mutateParentRefs(res.Id.Tenancy, route.ParentRefs) { changed = true } - for _, rule := range res.Data.Rules { + for _, rule := range route.Rules { for _, backend := range rule.BackendRefs { if backend.BackendRef == nil || backend.BackendRef.Ref == nil { continue @@ -43,26 +48,34 @@ func mutateTCPRoute(res *DecodedTCPRoute) (bool, error) { } } - return changed, nil + if !changed { + return nil + } + + return res.Data.MarshalFrom(&route) } -var ValidateTCPRoute = resource.DecodeAndValidate(validateTCPRoute) +func ValidateTCPRoute(res *pbresource.Resource) error { + var route pbmesh.TCPRoute + + if err := res.Data.UnmarshalTo(&route); err != nil { + return resource.NewErrDataParse(&route, err) + } -func validateTCPRoute(res *DecodedTCPRoute) error { var merr error - if err := validateParentRefs(res.Id, res.Data.ParentRefs); err != nil { + if err := validateParentRefs(res.Id, route.ParentRefs); err != nil { merr = multierror.Append(merr, err) } - if len(res.Data.Rules) > 1 { + if len(route.Rules) > 1 { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "rules", Wrapped: fmt.Errorf("must only specify a single rule for now"), }) } - for i, rule := range res.Data.Rules { + for i, rule := range route.Rules { wrapRuleErr := func(err error) error { return resource.ErrInvalidListElement{ Name: "rules", diff --git a/internal/mesh/internal/types/xroute.go b/internal/mesh/internal/types/xroute.go index 92e2136cd1356..619c9cb682435 100644 --- a/internal/mesh/internal/types/xroute.go +++ b/internal/mesh/internal/types/xroute.go @@ -288,17 +288,28 @@ func isValidRetryCondition(retryOn string) bool { func xRouteACLHooks[R XRouteData]() *resource.ACLHooks { hooks := &resource.ACLHooks{ - Read: resource.DecodeAndAuthorizeRead(aclReadHookXRoute[R]), - Write: resource.DecodeAndAuthorizeWrite(aclWriteHookXRoute[R]), + Read: aclReadHookXRoute[R], + Write: aclWriteHookXRoute[R], List: resource.NoOpACLListHook, } return hooks } -func aclReadHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.AuthorizerContext, res *resource.DecodedResource[R]) error { +func aclReadHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { + if res == nil { + return resource.ErrNeedResource + } + + dec, err := resource.Decode[R](res) + if err != nil { + return err + } + + route := dec.Data + // Need service:read on ALL of the services this is controlling traffic for. - for _, parentRef := range res.Data.GetParentRefs() { + for _, parentRef := range route.GetParentRefs() { parentAuthzContext := resource.AuthorizerContext(parentRef.Ref.GetTenancy()) parentServiceName := parentRef.Ref.GetName() @@ -310,9 +321,16 @@ func aclReadHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.Authorize return nil } -func aclWriteHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.AuthorizerContext, res *resource.DecodedResource[R]) error { +func aclWriteHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.AuthorizerContext, res *pbresource.Resource) error { + dec, err := resource.Decode[R](res) + if err != nil { + return err + } + + route := dec.Data + // Need service:write on ALL of the services this is controlling traffic for. - for _, parentRef := range res.Data.GetParentRefs() { + for _, parentRef := range route.GetParentRefs() { parentAuthzContext := resource.AuthorizerContext(parentRef.Ref.GetTenancy()) parentServiceName := parentRef.Ref.GetName() @@ -322,7 +340,7 @@ func aclWriteHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.Authoriz } // Need service:read on ALL of the services this directs traffic at. - for _, backendRef := range res.Data.GetUnderlyingBackendRefs() { + for _, backendRef := range route.GetUnderlyingBackendRefs() { backendAuthzContext := resource.AuthorizerContext(backendRef.Ref.GetTenancy()) backendServiceName := backendRef.Ref.GetName() diff --git a/internal/multicluster/exports.go b/internal/multicluster/exports.go deleted file mode 100644 index fcf5873d81ceb..0000000000000 --- a/internal/multicluster/exports.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package multicluster - -import ( - "github.com/hashicorp/consul/internal/multicluster/internal/types" - "github.com/hashicorp/consul/internal/resource" -) - -var ( - // API Group Information - APIGroup = types.GroupName - VersionV2Beta1 = types.VersionV2Beta1 - CurrentVersion = types.CurrentVersion -) - -// RegisterTypes adds all resource types within the "multicluster" API group -// to the given type registry -func RegisterTypes(r resource.Registry) { - types.Register(r) -} diff --git a/internal/multicluster/internal/types/computed_exported_services.go b/internal/multicluster/internal/types/computed_exported_services.go deleted file mode 100644 index 70c900c9b86cd..0000000000000 --- a/internal/multicluster/internal/types/computed_exported_services.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - ComputedExportedServicesName = "global" -) - -func RegisterComputedExportedServices(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmulticluster.ComputedExportedServicesType, - Proto: &pbmulticluster.ComputedExportedServices{}, - Scope: resource.ScopePartition, - Validate: ValidateComputedExportedServices, - ACLs: &resource.ACLHooks{ - Read: aclReadHookComputedExportedServices, - Write: aclWriteHookComputedExportedServices, - List: resource.NoOpACLListHook, - }, - }) -} - -func aclReadHookComputedExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshReadAllowed(authzContext) -} - -func aclWriteHookComputedExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshWriteAllowed(authzContext) -} diff --git a/internal/multicluster/internal/types/computed_exported_services_test.go b/internal/multicluster/internal/types/computed_exported_services_test.go deleted file mode 100644 index 79462c7088c32..0000000000000 --- a/internal/multicluster/internal/types/computed_exported_services_test.go +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/require" - "testing" -) - -func computedExportedServicesWithPartition(partitionName string) *pbmulticluster.ComputedExportedServices { - consumers := []*pbmulticluster.ComputedExportedService{ - { - Consumers: []*pbmulticluster.ComputedExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ComputedExportedServicesConsumer_Partition{ - Partition: partitionName, - }, - }, - }, - }, - } - return &pbmulticluster.ComputedExportedServices{ - Consumers: consumers, - } -} - -func computedExportedServicesWithPeer(peerName string) *pbmulticluster.ComputedExportedServices { - consumers := []*pbmulticluster.ComputedExportedService{ - { - Consumers: []*pbmulticluster.ComputedExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ComputedExportedServicesConsumer_Peer{ - Peer: peerName, - }, - }, - }, - }, - } - return &pbmulticluster.ComputedExportedServices{ - Consumers: consumers, - } -} - -func TestComputedExportedServicesValidations_InvalidName(t *testing.T) { - res := resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, "computed-exported-services"). - WithData(t, computedExportedServicesWithPeer("peer")). - Build() - - err := ValidateComputedExportedServices(res) - require.Error(t, err) - expectedError := errors.New("invalid \"name\" field: name can only be \"global\"") - require.ErrorAs(t, err, &expectedError) -} - -func TestComputedExportedServicesACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - readOK string - writeOK string - listOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - exportedServiceData := &pbmulticluster.ComputedExportedServices{} - res := resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, "global"). - WithData(t, exportedServiceData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh read policy": { - rules: `mesh = "read"`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh write policy": { - rules: `mesh = "write"`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - for _, tc := range cases { - aclTestCase := resourcetest.ACLTestCase{ - Rules: tc.rules, - Res: res, - ReadOK: tc.readOK, - WriteOK: tc.writeOK, - ListOK: tc.listOK, - } - resourcetest.RunACLTestCase(t, aclTestCase, registry) - } -} - -func TestComputedExportedServicesValidations(t *testing.T) { - type testcase struct { - Resource *pbresource.Resource - expectErrorCE []string - expectErrorENT []string - } - - isEnterprise := structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default" - - run := func(t *testing.T, tc testcase) { - expectError := tc.expectErrorCE - if isEnterprise { - expectError = tc.expectErrorENT - } - err := ValidateComputedExportedServices(tc.Resource) - if len(expectError) == 0 { - require.NoError(t, err) - } else { - require.Error(t, err) - for _, er := range expectError { - require.ErrorContains(t, err, er) - } - } - } - - cases := map[string]testcase{ - "computed exported services with peer": { - Resource: resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, ComputedExportedServicesName). - WithData(t, computedExportedServicesWithPeer("peer")). - Build(), - }, - "computed exported services with partition": { - Resource: resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, ComputedExportedServicesName). - WithData(t, computedExportedServicesWithPartition("partition")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can only be set in Enterprise`}, - }, - "computed exported services with peer empty": { - Resource: resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, ComputedExportedServicesName). - WithData(t, computedExportedServicesWithPeer("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "peer": can not be empty`}, - expectErrorENT: []string{`invalid element at index 0 of list "peer": can not be empty`}, - }, - "computed exported services with partition empty": { - Resource: resourcetest.Resource(pbmulticluster.ComputedExportedServicesType, ComputedExportedServicesName). - WithData(t, computedExportedServicesWithPartition("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can not be empty`, - `invalid element at index 0 of list "partition": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "partition": can not be empty`}, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/multicluster/internal/types/exported_services.go b/internal/multicluster/internal/types/exported_services.go deleted file mode 100644 index 87cebb244ab4e..0000000000000 --- a/internal/multicluster/internal/types/exported_services.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterExportedServices(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmulticluster.ExportedServicesType, - Proto: &pbmulticluster.ExportedServices{}, - Scope: resource.ScopeNamespace, - Validate: ValidateExportedServices, - ACLs: &resource.ACLHooks{ - Read: aclReadHookExportedServices, - Write: aclWriteHookExportedServices, - List: resource.NoOpACLListHook, - }, - }) -} - -func aclReadHookExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { - if res == nil { - return resource.ErrNeedResource - } - - var exportedService pbmulticluster.ExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - for _, serviceName := range exportedService.Services { - if err := authorizer.ToAllowAuthorizer().ServiceReadAllowed(serviceName, authzContext); err != nil { - return err - } - } - return nil -} - -func aclWriteHookExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - var exportedService pbmulticluster.ExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - for _, serviceName := range exportedService.Services { - if err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(serviceName, authzContext); err != nil { - return err - } - } - return nil -} diff --git a/internal/multicluster/internal/types/exported_services_test.go b/internal/multicluster/internal/types/exported_services_test.go deleted file mode 100644 index ea80b16e43df4..0000000000000 --- a/internal/multicluster/internal/types/exported_services_test.go +++ /dev/null @@ -1,218 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "errors" - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/require" - "testing" -) - -func inValidExportedServices() *pbmulticluster.ExportedServices { - return &pbmulticluster.ExportedServices{} -} - -func exportedServicesWithPeer(peerName string) *pbmulticluster.ExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Peer{ - Peer: peerName, - }, - }, - } - return &pbmulticluster.ExportedServices{ - Services: []string{"api", "frontend", "backend"}, - Consumers: consumers, - } -} - -func exportedServicesWithPartition(partitionName string) *pbmulticluster.ExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Partition{ - Partition: partitionName, - }, - }, - } - return &pbmulticluster.ExportedServices{ - Services: []string{"api", "frontend", "backend"}, - Consumers: consumers, - } -} - -func exportedServicesWithSamenessGroup(samenessGroupName string) *pbmulticluster.ExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_SamenessGroup{ - SamenessGroup: samenessGroupName, - }, - }, - } - return &pbmulticluster.ExportedServices{ - Services: []string{"api", "frontend", "backend"}, - Consumers: consumers, - } -} - -func TestExportedServicesValidation_NoServices(t *testing.T) { - res := resourcetest.Resource(pbmulticluster.ExportedServicesType, "exportedservices1"). - WithData(t, inValidExportedServices()). - Build() - - err := ValidateExportedServices(res) - require.Error(t, err) - expectedError := errors.New("invalid \"services\" field: at least one service must be set") - require.ErrorAs(t, err, &expectedError) -} - -func TestExportedServicesACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - readOK string - writeOK string - listOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - exportedServiceData := &pbmulticluster.ExportedServices{ - Services: []string{"api", "backend"}, - } - res := resourcetest.Resource(pbmulticluster.ExportedServicesType, "exps"). - WithData(t, exportedServiceData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "all services has read policy": { - rules: `service "api" { policy = "read" } service "backend" {policy = "read"}`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "all services has write policy": { - rules: `service "api" { policy = "write" } service "backend" {policy = "write"}`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - "only one services has read policy": { - rules: `service "api" { policy = "read" }`, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "only one services has write policy": { - rules: `service "api" { policy = "write" }`, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - } - - for _, tc := range cases { - aclTestCase := resourcetest.ACLTestCase{ - Rules: tc.rules, - Res: res, - ReadOK: tc.readOK, - WriteOK: tc.writeOK, - ListOK: tc.listOK, - } - resourcetest.RunACLTestCase(t, aclTestCase, registry) - } -} - -func TestExportedServicesValidation(t *testing.T) { - type testcase struct { - Resource *pbresource.Resource - expectErrorCE []string - expectErrorENT []string - } - - isEnterprise := structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default" - - run := func(t *testing.T, tc testcase) { - expectError := tc.expectErrorCE - if isEnterprise { - expectError = tc.expectErrorENT - } - err := ValidateExportedServices(tc.Resource) - if len(expectError) == 0 { - require.NoError(t, err) - } else { - require.Error(t, err) - for _, er := range expectError { - require.ErrorContains(t, err, er) - } - } - } - - cases := map[string]testcase{ - "exported services with peer": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithPeer("peer")). - Build(), - }, - "exported services with partition": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithPartition("partition")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can only be set in Enterprise`}, - }, - "exported services with sameness_group": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithSamenessGroup("sameness_group")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - }, - "exported services with peer empty": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithPeer("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - expectErrorENT: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - }, - "exported services with partition empty": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithPartition("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can not be empty`, - `invalid element at index 0 of list "partition": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "partition": can not be empty`}, - }, - "exported services with sameness_group empty": { - Resource: resourcetest.Resource(pbmulticluster.ExportedServicesType, "exported-services"). - WithData(t, exportedServicesWithSamenessGroup("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can not be empty`, - `invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "sameness_group": can not be empty`}, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/multicluster/internal/types/helpers.go b/internal/multicluster/internal/types/helpers.go deleted file mode 100644 index 5dac17f1e7a97..0000000000000 --- a/internal/multicluster/internal/types/helpers.go +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "fmt" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/hashicorp/go-multierror" -) - -func validateExportedServiceConsumerCommon(consumer *pbmulticluster.ExportedServicesConsumer, indx int) error { - switch consumer.GetConsumerTenancy().(type) { - case *pbmulticluster.ExportedServicesConsumer_Peer: - { - if consumer.GetPeer() == "" || consumer.GetPeer() == "local" { - return resource.ErrInvalidListElement{ - Name: "peer", - Index: indx, - Wrapped: fmt.Errorf("can not be empty or local"), - } - } - } - case *pbmulticluster.ExportedServicesConsumer_Partition: - { - if consumer.GetPartition() == "" { - return resource.ErrInvalidListElement{ - Name: "partition", - Index: indx, - Wrapped: fmt.Errorf("can not be empty"), - } - } - } - case *pbmulticluster.ExportedServicesConsumer_SamenessGroup: - { - if consumer.GetSamenessGroup() == "" { - return resource.ErrInvalidListElement{ - Name: "sameness_group", - Index: indx, - Wrapped: fmt.Errorf("can not be empty"), - } - } - } - } - return nil -} - -func validateExportedServicesConsumersEnterprise(consumers []*pbmulticluster.ExportedServicesConsumer) error { - var merr error - - for indx, consumer := range consumers { - vmerr := validateExportedServiceConsumerCommon(consumer, indx) - if vmerr != nil { - merr = multierror.Append(merr, vmerr) - } - vmerr = validateExportedServicesConsumer(consumer, indx) - if vmerr != nil { - merr = multierror.Append(merr, vmerr) - } - } - - return merr -} - -func ValidateExportedServices(res *pbresource.Resource) error { - var exportedService pbmulticluster.ExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - var merr error - - if len(exportedService.Services) == 0 { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "services", - Wrapped: fmt.Errorf("at least one service must be set"), - }) - } - - vmerr := validateExportedServicesConsumersEnterprise(exportedService.Consumers) - - if vmerr != nil { - merr = multierror.Append(merr, vmerr) - } - - return merr -} - -func ValidateNamespaceExportedServices(res *pbresource.Resource) error { - var exportedService pbmulticluster.NamespaceExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - return validateExportedServicesConsumersEnterprise(exportedService.Consumers) -} - -func ValidatePartitionExportedServices(res *pbresource.Resource) error { - var exportedService pbmulticluster.PartitionExportedServices - - if err := res.Data.UnmarshalTo(&exportedService); err != nil { - return resource.NewErrDataParse(&exportedService, err) - } - - return validateExportedServicesConsumersEnterprise(exportedService.Consumers) -} - -func ValidateComputedExportedServices(res *pbresource.Resource) error { - var computedExportedServices pbmulticluster.ComputedExportedServices - - if err := res.Data.UnmarshalTo(&computedExportedServices); err != nil { - return resource.NewErrDataParse(&computedExportedServices, err) - } - - var merr error - - if res.Id.Name != ComputedExportedServicesName { - merr = multierror.Append(merr, resource.ErrInvalidField{ - Name: "name", - Wrapped: fmt.Errorf("name can only be \"global\""), - }) - } - - vmerr := ValidateComputedExportedServicesEnterprise(&computedExportedServices) - - if vmerr != nil { - merr = multierror.Append(merr, vmerr) - } - - return merr -} diff --git a/internal/multicluster/internal/types/helpers_ce.go b/internal/multicluster/internal/types/helpers_ce.go deleted file mode 100644 index b997b8671ad05..0000000000000 --- a/internal/multicluster/internal/types/helpers_ce.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package types - -import ( - "fmt" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/go-multierror" -) - -func validateExportedServicesConsumer(consumer *pbmulticluster.ExportedServicesConsumer, indx int) error { - switch consumer.GetConsumerTenancy().(type) { - case *pbmulticluster.ExportedServicesConsumer_Partition: - return resource.ErrInvalidListElement{ - Name: "partition", - Index: indx, - Wrapped: fmt.Errorf("can only be set in Enterprise"), - } - case *pbmulticluster.ExportedServicesConsumer_SamenessGroup: - return resource.ErrInvalidListElement{ - Name: "sameness_group", - Index: indx, - Wrapped: fmt.Errorf("can only be set in Enterprise"), - } - } - return nil -} - -func ValidateComputedExportedServicesEnterprise(computedExportedServices *pbmulticluster.ComputedExportedServices) error { - - var merr error - - for indx, consumer := range computedExportedServices.GetConsumers() { - for _, computedExportedServiceConsumer := range consumer.GetConsumers() { - switch computedExportedServiceConsumer.GetConsumerTenancy().(type) { - case *pbmulticluster.ComputedExportedServicesConsumer_Partition: - merr = multierror.Append(merr, resource.ErrInvalidListElement{ - Name: "partition", - Index: indx, - Wrapped: fmt.Errorf("can only be set in Enterprise"), - }) - if computedExportedServiceConsumer.GetPartition() == "" { - merr = multierror.Append(merr, resource.ErrInvalidListElement{ - Name: "partition", - Index: indx, - Wrapped: fmt.Errorf("can not be empty"), - }) - } - case *pbmulticluster.ComputedExportedServicesConsumer_Peer: - if computedExportedServiceConsumer.GetPeer() == "" { - merr = multierror.Append(merr, resource.ErrInvalidListElement{ - Name: "peer", - Index: indx, - Wrapped: fmt.Errorf("can not be empty"), - }) - } - } - } - } - - return merr -} diff --git a/internal/multicluster/internal/types/namespace_exported_services.go b/internal/multicluster/internal/types/namespace_exported_services.go deleted file mode 100644 index 857ea868b8e96..0000000000000 --- a/internal/multicluster/internal/types/namespace_exported_services.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterNamespaceExportedServices(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmulticluster.NamespaceExportedServicesType, - Proto: &pbmulticluster.NamespaceExportedServices{}, - Scope: resource.ScopeNamespace, - Validate: ValidateNamespaceExportedServices, - ACLs: &resource.ACLHooks{ - Read: aclReadHookNamespaceExportedServices, - Write: aclWriteHookNamespaceExportedServices, - List: resource.NoOpACLListHook, - }, - }) -} - -func aclReadHookNamespaceExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshReadAllowed(authzContext) -} - -func aclWriteHookNamespaceExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshWriteAllowed(authzContext) -} diff --git a/internal/multicluster/internal/types/namespace_exported_services_test.go b/internal/multicluster/internal/types/namespace_exported_services_test.go deleted file mode 100644 index ab88a03767fce..0000000000000 --- a/internal/multicluster/internal/types/namespace_exported_services_test.go +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/require" - "testing" -) - -func validNamespaceExportedServicesWithPeer(peerName string) *pbmulticluster.NamespaceExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Peer{ - Peer: peerName, - }, - }, - } - return &pbmulticluster.NamespaceExportedServices{ - Consumers: consumers, - } -} - -func validNamespaceExportedServicesWithPartition(partitionName string) *pbmulticluster.NamespaceExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Partition{ - Partition: partitionName, - }, - }, - } - return &pbmulticluster.NamespaceExportedServices{ - Consumers: consumers, - } -} - -func validNamespaceExportedServicesWithSamenessGroup(samenessGroupName string) *pbmulticluster.NamespaceExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_SamenessGroup{ - SamenessGroup: samenessGroupName, - }, - }, - } - return &pbmulticluster.NamespaceExportedServices{ - Consumers: consumers, - } -} -func TestNamespaceExportedServicesACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - readOK string - writeOK string - listOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh read policy": { - rules: `mesh = "read"`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh write policy": { - rules: `mesh = "write"`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - exportedServiceData := &pbmulticluster.NamespaceExportedServices{} - res := resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, exportedServiceData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - for _, tc := range cases { - aclTestCase := resourcetest.ACLTestCase{ - Rules: tc.rules, - Res: res, - ReadOK: tc.readOK, - WriteOK: tc.writeOK, - ListOK: tc.listOK, - } - resourcetest.RunACLTestCase(t, aclTestCase, registry) - } -} - -func TestNamespaceExportedServicesValidations(t *testing.T) { - type testcase struct { - Resource *pbresource.Resource - expectErrorCE []string - expectErrorENT []string - } - - isEnterprise := structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default" - - run := func(t *testing.T, tc testcase) { - expectError := tc.expectErrorCE - if isEnterprise { - expectError = tc.expectErrorENT - } - err := ValidateNamespaceExportedServices(tc.Resource) - if len(expectError) == 0 { - require.NoError(t, err) - } else { - require.Error(t, err) - for _, er := range expectError { - require.ErrorContains(t, err, er) - } - } - } - - cases := map[string]testcase{ - "namespace exported services with peer": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithPeer("peer")). - Build(), - }, - "namespace exported services with partition": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithPartition("partition")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can only be set in Enterprise`}, - }, - "namespace exported services with sameness_group": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithSamenessGroup("sameness_group")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - }, - "namespace exported services with peer empty": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithPeer("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - expectErrorENT: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - }, - "namespace exported services with partition empty": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithPartition("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can not be empty`, - `invalid element at index 0 of list "partition": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "partition": can not be empty`}, - }, - "namespace exported services with sameness_group empty": { - Resource: resourcetest.Resource(pbmulticluster.NamespaceExportedServicesType, "namespace-exported-services"). - WithData(t, validNamespaceExportedServicesWithSamenessGroup("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can not be empty`, - `invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "sameness_group": can not be empty`}, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/multicluster/internal/types/partition_exported_services.go b/internal/multicluster/internal/types/partition_exported_services.go deleted file mode 100644 index 110eb5d6efa13..0000000000000 --- a/internal/multicluster/internal/types/partition_exported_services.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -func RegisterPartitionExportedServices(r resource.Registry) { - r.Register(resource.Registration{ - Type: pbmulticluster.PartitionExportedServicesType, - Proto: &pbmulticluster.PartitionExportedServices{}, - Scope: resource.ScopePartition, - Validate: ValidatePartitionExportedServices, - ACLs: &resource.ACLHooks{ - Read: aclReadHookPartitionExportedServices, - Write: aclWriteHookPartitionExportedServices, - List: resource.NoOpACLListHook, - }, - }) -} - -func aclReadHookPartitionExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshReadAllowed(authzContext) -} - -func aclWriteHookPartitionExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { - return authorizer.ToAllowAuthorizer().MeshWriteAllowed(authzContext) -} diff --git a/internal/multicluster/internal/types/partition_exported_services_test.go b/internal/multicluster/internal/types/partition_exported_services_test.go deleted file mode 100644 index fdd90ef11d12f..0000000000000 --- a/internal/multicluster/internal/types/partition_exported_services_test.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/agent/structs" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/resourcetest" - pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v2beta1" - "github.com/hashicorp/consul/proto-public/pbresource" - "github.com/stretchr/testify/require" - "testing" -) - -func validPartitionExportedServicesWithPeer(peerName string) *pbmulticluster.PartitionExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Peer{ - Peer: peerName, - }, - }, - } - return &pbmulticluster.PartitionExportedServices{ - Consumers: consumers, - } -} - -func validPartitionExportedServicesWithPartition(partitionName string) *pbmulticluster.PartitionExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_Partition{ - Partition: partitionName, - }, - }, - } - return &pbmulticluster.PartitionExportedServices{ - Consumers: consumers, - } -} - -func validPartitionExportedServicesWithSamenessGroup(samenessGroupName string) *pbmulticluster.PartitionExportedServices { - consumers := []*pbmulticluster.ExportedServicesConsumer{ - { - ConsumerTenancy: &pbmulticluster.ExportedServicesConsumer_SamenessGroup{ - SamenessGroup: samenessGroupName, - }, - }, - } - return &pbmulticluster.PartitionExportedServices{ - Consumers: consumers, - } -} - -func TestPartitionExportedServicesACLs(t *testing.T) { - // Wire up a registry to generically invoke hooks - registry := resource.NewRegistry() - Register(registry) - - type testcase struct { - rules string - readOK string - writeOK string - listOK string - } - - const ( - DENY = resourcetest.DENY - ALLOW = resourcetest.ALLOW - DEFAULT = resourcetest.DEFAULT - ) - - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh read policy": { - rules: `mesh = "read"`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "mesh write policy": { - rules: `mesh = "write"`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, - } - - exportedServiceData := &pbmulticluster.PartitionExportedServices{} - res := resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, exportedServiceData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - for _, tc := range cases { - aclTestCase := resourcetest.ACLTestCase{ - Rules: tc.rules, - Res: res, - ReadOK: tc.readOK, - WriteOK: tc.writeOK, - ListOK: tc.listOK, - } - resourcetest.RunACLTestCase(t, aclTestCase, registry) - } -} - -func TestPartitionExportedServicesValidations(t *testing.T) { - type testcase struct { - Resource *pbresource.Resource - expectErrorCE []string - expectErrorENT []string - } - - isEnterprise := structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default" - - run := func(t *testing.T, tc testcase) { - expectError := tc.expectErrorCE - if isEnterprise { - expectError = tc.expectErrorENT - } - err := ValidatePartitionExportedServices(tc.Resource) - if len(expectError) == 0 { - require.NoError(t, err) - } else { - require.Error(t, err) - for _, er := range expectError { - require.ErrorContains(t, err, er) - } - } - } - - cases := map[string]testcase{ - "partition exported services with peer": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithPeer("peer")). - Build(), - }, - "partition exported services with partition": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithPartition("partition")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can only be set in Enterprise`}, - }, - "partition exported services with sameness_group": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithSamenessGroup("sameness_group")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - }, - "partition exported services with peer empty": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithPeer("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - expectErrorENT: []string{`invalid element at index 0 of list "peer": can not be empty or local`}, - }, - "partition exported services with partition empty": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithPartition("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "partition": can not be empty`, - `invalid element at index 0 of list "partition": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "partition": can not be empty`}, - }, - "partition exported services with sameness_group empty": { - Resource: resourcetest.Resource(pbmulticluster.PartitionExportedServicesType, "partition-exported-services"). - WithData(t, validPartitionExportedServicesWithSamenessGroup("")). - Build(), - expectErrorCE: []string{`invalid element at index 0 of list "sameness_group": can not be empty`, - `invalid element at index 0 of list "sameness_group": can only be set in Enterprise`}, - expectErrorENT: []string{`invalid element at index 0 of list "sameness_group": can not be empty`}, - }, - } - - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) - }) - } -} diff --git a/internal/multicluster/internal/types/types.go b/internal/multicluster/internal/types/types.go deleted file mode 100644 index 9ee6691e19ec8..0000000000000 --- a/internal/multicluster/internal/types/types.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package types - -import ( - "github.com/hashicorp/consul/internal/resource" -) - -const ( - GroupName = "multicluster" - VersionV2Beta1 = "v2beta1" - CurrentVersion = VersionV2Beta1 -) - -func Register(r resource.Registry) { - RegisterExportedServices(r) - RegisterNamespaceExportedServices(r) - RegisterPartitionExportedServices(r) - RegisterComputedExportedServices(r) -} diff --git a/internal/resource/decode.go b/internal/resource/decode.go index d96cb79a9a7ca..ba9abd87d60d9 100644 --- a/internal/resource/decode.go +++ b/internal/resource/decode.go @@ -16,10 +16,8 @@ import ( // DecodedResource is a generic holder to contain an original Resource and its // decoded contents. type DecodedResource[T proto.Message] struct { - // Embedding here allows us to shadow the Resource.Data Any field to fake out - // using a single struct with inlined data. - *pbresource.Resource - Data T + Resource *pbresource.Resource + Data T } func (d *DecodedResource[T]) GetResource() *pbresource.Resource { diff --git a/internal/resource/demo/controller.go b/internal/resource/demo/controller.go index a8757fcae2624..7f1bba902ea51 100644 --- a/internal/resource/demo/controller.go +++ b/internal/resource/demo/controller.go @@ -71,7 +71,7 @@ func (r *artistReconciler) Reconcile(ctx context.Context, rt controller.Runtime, actualAlbums, err := rt.Client.List(ctx, &pbresource.ListRequest{ Type: TypeV2Album, Tenancy: res.Id.Tenancy, - NamePrefix: fmt.Sprintf("%s-", res.Id.Name), + NamePrefix: fmt.Sprintf("%s/", res.Id.Name), }) if err != nil { return err diff --git a/internal/resource/demo/demo.go b/internal/resource/demo/demo.go index 12fced6718e61..8e978c9fb49ab 100644 --- a/internal/resource/demo/demo.go +++ b/internal/resource/demo/demo.go @@ -354,7 +354,7 @@ func generateV2Album(artistID *pbresource.ID, rand *rand.Rand) (*pbresource.Reso Id: &pbresource.ID{ Type: TypeV2Album, Tenancy: clone(artistID.Tenancy), - Name: fmt.Sprintf("%s-%s-%s", artistID.Name, strings.ToLower(adjective), strings.ToLower(noun)), + Name: fmt.Sprintf("%s/%s-%s", artistID.Name, strings.ToLower(adjective), strings.ToLower(noun)), }, Owner: artistID, Data: data, diff --git a/internal/resource/hooks.go b/internal/resource/hooks.go deleted file mode 100644 index 2b9d72b88925f..0000000000000 --- a/internal/resource/hooks.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/proto-public/pbresource" - "google.golang.org/protobuf/proto" -) - -// DecodedValidationHook is the function signature needed for usage with the DecodeAndValidate function -type DecodedValidationHook[T proto.Message] func(*DecodedResource[T]) error - -// DecodeAndValidate will generate a validation hook function that decodes the specified type and -// passes it off to another validation hook. This is mainly a convenience to avoid many other -// validation hooks needing to attempt decoding the data and erroring in a consistent manner. -func DecodeAndValidate[T proto.Message](fn DecodedValidationHook[T]) ValidationHook { - return func(res *pbresource.Resource) error { - decoded, err := Decode[T](res) - if err != nil { - return err - } - - return fn(decoded) - } -} - -// DecodedMutationHook is the function signature needed for usage with the DecodeAndMutate function -// The boolean return value indicates whether the Data field within the DecodedResource was modified. -// When true, the DecodeAndMutate hook function will automatically re-encode the Any data and store -// it on the internal Resource's Data field. -type DecodedMutationHook[T proto.Message] func(*DecodedResource[T]) (bool, error) - -// DecodeAndMutate will generate a MutationHook that decodes the specified type and passes it -// off to another mutation hook. This is mainly a convenience to avoid other mutation hooks -// needing to decode and potentially reencode the Any data. When the inner mutation hook returns -// no error and that the Data was modified (true for the boolean return value), the generated -// hook will reencode the Any data back into the Resource wrapper -func DecodeAndMutate[T proto.Message](fn DecodedMutationHook[T]) MutationHook { - return func(res *pbresource.Resource) error { - decoded, err := Decode[T](res) - if err != nil { - return err - } - - modified, err := fn(decoded) - if err != nil { - return err - } - - if modified { - return decoded.Resource.Data.MarshalFrom(decoded.Data) - } - return nil - } -} - -// DecodedAuthorizationHook is the function signature needed for usage with the DecodeAndAuthorizeWrite -// and DecodeAndAuthorizeRead functions. -type DecodedAuthorizationHook[T proto.Message] func(acl.Authorizer, *acl.AuthorizerContext, *DecodedResource[T]) error - -// DecodeAndAuthorizeWrite will generate an ACLAuthorizeWriteHook that decodes the specified type and passes -// it off to another authorization hook. This is mainly a convenience to avoid many other write authorization -// hooks needing to attempt decoding the data and erroring in a consistent manner. -func DecodeAndAuthorizeWrite[T proto.Message](fn DecodedAuthorizationHook[T]) ACLAuthorizeWriteHook { - return func(authz acl.Authorizer, ctx *acl.AuthorizerContext, res *pbresource.Resource) error { - decoded, err := Decode[T](res) - if err != nil { - return err - } - - return fn(authz, ctx, decoded) - } -} - -// DecodeAndAuthorizeRead will generate an ACLAuthorizeReadHook that decodes the specified type and passes -// it off to another authorization hook. This is mainly a convenience to avoid many other read authorization -// hooks needing to attempt decoding the data and erroring in a consistent manner. -func DecodeAndAuthorizeRead[T proto.Message](fn DecodedAuthorizationHook[T]) ACLAuthorizeReadHook { - return func(authz acl.Authorizer, ctx *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { - if res == nil { - return ErrNeedResource - } - - decoded, err := Decode[T](res) - if err != nil { - return err - } - - return fn(authz, ctx, decoded) - } -} - -type ReadAuthorizationWithResourceHook func(acl.Authorizer, *acl.AuthorizerContext, *pbresource.Resource) error - -// AuthorizeReadWithResource is a small wrapper to ensure that the authorization function is -// invoked with the full resource being read instead of just an id. -func AuthorizeReadWithResource(fn ReadAuthorizationWithResourceHook) ACLAuthorizeReadHook { - return func(authz acl.Authorizer, ctx *acl.AuthorizerContext, id *pbresource.ID, res *pbresource.Resource) error { - if res == nil { - return ErrNeedResource - } - - return fn(authz, ctx, res) - } -} diff --git a/internal/resource/hooks_test.go b/internal/resource/hooks_test.go deleted file mode 100644 index d9fa4d4272b74..0000000000000 --- a/internal/resource/hooks_test.go +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/consul/acl" - "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/resource/demo" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/proto-public/pbresource" - pbdemo "github.com/hashicorp/consul/proto/private/pbdemo/v2" - "github.com/stretchr/testify/require" -) - -func TestDecodeAndValidate(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("ok", func(t *testing.T) { - err := resource.DecodeAndValidate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) error { - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - return nil - })(res) - - require.NoError(t, err) - }) - - t.Run("inner-validation-error", func(t *testing.T) { - fakeErr := fmt.Errorf("fake") - - err := resource.DecodeAndValidate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) error { - return fakeErr - })(res) - - require.Error(t, err) - require.Equal(t, fakeErr, err) - }) - - t.Run("decode-error", func(t *testing.T) { - err := resource.DecodeAndValidate[*pbdemo.Album](func(dec *resource.DecodedResource[*pbdemo.Album]) error { - require.Fail(t, "callback should not be called when decoding fails") - return nil - })(res) - - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) - }) -} - -func TestDecodeAndMutate(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("no-writeback", func(t *testing.T) { - original := res.Data.Value - - err := resource.DecodeAndMutate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) (bool, error) { - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - // we are going to change the data but not tell the outer hook about it - dec.Data.Name = "changed" - - return false, nil - })(res) - - require.NoError(t, err) - // Ensure that the outer hook didn't overwrite the resources data because we told it not to - require.Equal(t, original, res.Data.Value) - }) - - t.Run("writeback", func(t *testing.T) { - original := res.Data.Value - - err := resource.DecodeAndMutate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) (bool, error) { - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - dec.Data.Name = "changed" - - return true, nil - })(res) - - require.NoError(t, err) - // Ensure that the outer hook reencoded the Any data because we told it to. - require.NotEqual(t, original, res.Data.Value) - }) - - t.Run("inner-mutation-error", func(t *testing.T) { - fakeErr := fmt.Errorf("fake") - - err := resource.DecodeAndMutate[*pbdemo.Artist](func(dec *resource.DecodedResource[*pbdemo.Artist]) (bool, error) { - return false, fakeErr - })(res) - - require.Error(t, err) - require.Equal(t, fakeErr, err) - }) - - t.Run("decode-error", func(t *testing.T) { - err := resource.DecodeAndMutate[*pbdemo.Album](func(dec *resource.DecodedResource[*pbdemo.Album]) (bool, error) { - require.Fail(t, "callback should not be called when decoding fails") - return false, nil - })(res) - - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) - }) -} - -func TestDecodeAndAuthorizeWrite(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("allowed", func(t *testing.T) { - err := resource.DecodeAndAuthorizeWrite[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - require.NotNil(t, a) - require.NotNil(t, c) - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - // access allowed - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, res) - - require.NoError(t, err) - }) - - t.Run("denied", func(t *testing.T) { - err := resource.DecodeAndAuthorizeWrite[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - return acl.PermissionDenied("fake") - })(acl.DenyAll(), nil, res) - - require.Error(t, err) - require.True(t, acl.IsErrPermissionDenied(err)) - }) - - t.Run("decode-error", func(t *testing.T) { - err := resource.DecodeAndAuthorizeWrite[*pbdemo.Album](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Album]) error { - require.Fail(t, "callback should not be called when decoding fails") - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, res) - - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) - }) -} - -func TestDecodeAndAuthorizeRead(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("allowed", func(t *testing.T) { - err := resource.DecodeAndAuthorizeRead[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - require.NotNil(t, a) - require.NotNil(t, c) - require.NotNil(t, dec.Resource) - require.NotNil(t, dec.Data) - - // access allowed - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, res) - - require.NoError(t, err) - }) - - t.Run("denied", func(t *testing.T) { - err := resource.DecodeAndAuthorizeRead[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - return acl.PermissionDenied("fake") - })(acl.DenyAll(), nil, nil, res) - - require.Error(t, err) - require.True(t, acl.IsErrPermissionDenied(err)) - }) - - t.Run("decode-error", func(t *testing.T) { - err := resource.DecodeAndAuthorizeRead[*pbdemo.Album](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Album]) error { - require.Fail(t, "callback should not be called when decoding fails") - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, res) - - require.Error(t, err) - require.ErrorAs(t, err, &resource.ErrDataParse{}) - }) - - t.Run("err-need-resource", func(t *testing.T) { - err := resource.DecodeAndAuthorizeRead[*pbdemo.Artist](func(a acl.Authorizer, c *acl.AuthorizerContext, dec *resource.DecodedResource[*pbdemo.Artist]) error { - require.Fail(t, "callback should not be called when no resource was provided to be decoded") - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, nil) - - require.Error(t, err) - require.ErrorIs(t, err, resource.ErrNeedResource) - }) -} - -func TestAuthorizeReadWithResource(t *testing.T) { - res := rtest.Resource(demo.TypeV2Artist, "babypants"). - WithData(t, &pbdemo.Artist{Name: "caspar babypants"}). - Build() - - t.Run("allowed", func(t *testing.T) { - err := resource.AuthorizeReadWithResource(func(a acl.Authorizer, c *acl.AuthorizerContext, res *pbresource.Resource) error { - require.NotNil(t, a) - require.NotNil(t, c) - require.NotNil(t, res) - - // access allowed - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, res) - - require.NoError(t, err) - }) - - t.Run("denied", func(t *testing.T) { - err := resource.AuthorizeReadWithResource(func(a acl.Authorizer, c *acl.AuthorizerContext, res *pbresource.Resource) error { - return acl.PermissionDenied("fake") - })(acl.DenyAll(), nil, nil, res) - - require.Error(t, err) - require.True(t, acl.IsErrPermissionDenied(err)) - }) - - t.Run("err-need-resource", func(t *testing.T) { - err := resource.AuthorizeReadWithResource(func(a acl.Authorizer, c *acl.AuthorizerContext, res *pbresource.Resource) error { - require.Fail(t, "callback should not be called when no resource was provided to be decoded") - return nil - })(acl.DenyAll(), &acl.AuthorizerContext{}, nil, nil) - - require.Error(t, err) - require.ErrorIs(t, err, resource.ErrNeedResource) - }) -} diff --git a/internal/resource/http/http_test.go b/internal/resource/http/http_test.go index aeb85f0b8332a..50f50fbe39488 100644 --- a/internal/resource/http/http_test.go +++ b/internal/resource/http/http_test.go @@ -42,7 +42,7 @@ func TestResourceHandler_InputValidation(t *testing.T) { request *http.Request response *httptest.ResponseRecorder expectedResponseCode int - responseBodyContains string + expectedErrorMessage string } client := svctest.RunResourceService(t, demo.RegisterTypes) resourceHandler := resourceHandler{ @@ -72,7 +72,7 @@ func TestResourceHandler_InputValidation(t *testing.T) { `)), response: httptest.NewRecorder(), expectedResponseCode: http.StatusBadRequest, - responseBodyContains: "resource.id.name invalid", + expectedErrorMessage: "rpc error: code = InvalidArgument desc = resource.id.name is required", }, { description: "wrong schema", @@ -89,21 +89,21 @@ func TestResourceHandler_InputValidation(t *testing.T) { `)), response: httptest.NewRecorder(), expectedResponseCode: http.StatusBadRequest, - responseBodyContains: "Request body didn't follow the resource schema", + expectedErrorMessage: "Request body didn't follow the resource schema", }, { description: "invalid request body", request: httptest.NewRequest("PUT", "/keith-urban?partition=default&peer_name=local&namespace=default", strings.NewReader("bad-input")), response: httptest.NewRecorder(), expectedResponseCode: http.StatusBadRequest, - responseBodyContains: "Request body format is invalid", + expectedErrorMessage: "Request body format is invalid", }, { description: "no id", request: httptest.NewRequest("DELETE", "/?partition=default&peer_name=local&namespace=default", strings.NewReader("")), response: httptest.NewRecorder(), expectedResponseCode: http.StatusBadRequest, - responseBodyContains: "id.name invalid", + expectedErrorMessage: "rpc error: code = InvalidArgument desc = id.name is required", }, } @@ -119,7 +119,7 @@ func TestResourceHandler_InputValidation(t *testing.T) { require.NoError(t, err) require.Equal(t, tc.expectedResponseCode, tc.response.Result().StatusCode) - require.Contains(t, string(b), tc.responseBodyContains) + require.Equal(t, tc.expectedErrorMessage, string(b)) }) } } @@ -157,7 +157,7 @@ func TestResourceWriteHandler(t *testing.T) { require.Equal(t, http.StatusForbidden, rsp.Result().StatusCode) }) - var readRsp *pbresource.ReadResponse + t.Run("should write to the resource backend", func(t *testing.T) { rsp := httptest.NewRecorder() req := httptest.NewRequest("PUT", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default", strings.NewReader(` @@ -183,8 +183,7 @@ func TestResourceWriteHandler(t *testing.T) { require.Equal(t, "Keith Urban", result["data"].(map[string]any)["name"]) require.Equal(t, "keith-urban", result["id"].(map[string]any)["name"]) - var err error - readRsp, err = client.Read(testutil.TestContext(t), &pbresource.ReadRequest{ + readRsp, err := client.Read(testutil.TestContext(t), &pbresource.ReadRequest{ Id: &pbresource.ID{ Type: demo.TypeV2Artist, Tenancy: resource.DefaultNamespacedTenancy(), @@ -201,7 +200,7 @@ func TestResourceWriteHandler(t *testing.T) { t.Run("should update the record with version parameter", func(t *testing.T) { rsp := httptest.NewRecorder() - req := httptest.NewRequest("PUT", fmt.Sprintf("/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default&version=%s", readRsp.Resource.Version), strings.NewReader(` + req := httptest.NewRequest("PUT", "/demo/v2/artist/keith-urban?partition=default&peer_name=local&namespace=default&version=1", strings.NewReader(` { "metadata": { "foo": "bar" diff --git a/internal/resource/registry.go b/internal/resource/registry.go index 7897ffb1b4bce..20c1f4dc41a85 100644 --- a/internal/resource/registry.go +++ b/internal/resource/registry.go @@ -42,17 +42,6 @@ type Registry interface { Types() []Registration } -// ValidationHook is the function signature for a validation hook. These hooks can inspect -// the data as they see fit but are expected to not mutate the data in any way. If Go -// supported it, we would pass something akin to a const pointer into the callback to have -// the compiler enforce this immutability. -type ValidationHook func(*pbresource.Resource) error - -// MutationHook is the function signature for a validation hook. These hooks can inspect -// and mutate the resource. If modifying the resources Data, the hook needs to ensure that -// the data gets reencoded and stored back to the Data field. -type MutationHook func(*pbresource.Resource) error - type Registration struct { // Type is the GVK of the resource type. Type *pbresource.Type @@ -67,13 +56,13 @@ type Registration struct { // Validate is called to structurally validate the resource (e.g. // check for required fields). Validate can assume that Mutate // has been called. - Validate ValidationHook + Validate func(*pbresource.Resource) error // Mutate is called to fill out any autogenerated fields (e.g. UUIDs) or // apply defaults before validation. Mutate can assume that // Resource.ID is populated and has non-empty tenancy fields. This does // not mean those tenancy fields actually exist. - Mutate MutationHook + Mutate func(*pbresource.Resource) error // Scope describes the tenancy scope of a resource. Scope Scope @@ -81,10 +70,6 @@ type Registration struct { var ErrNeedResource = errors.New("authorization check requires the entire resource") -type ACLAuthorizeReadHook func(acl.Authorizer, *acl.AuthorizerContext, *pbresource.ID, *pbresource.Resource) error -type ACLAuthorizeWriteHook func(acl.Authorizer, *acl.AuthorizerContext, *pbresource.Resource) error -type ACLAuthorizeListHook func(acl.Authorizer, *acl.AuthorizerContext) error - type ACLHooks struct { // Read is used to authorize Read RPCs and to filter results in List // RPCs. @@ -94,17 +79,17 @@ type ACLHooks struct { // check will be deferred until the data is fetched from the storage layer. // // If it is omitted, `operator:read` permission is assumed. - Read ACLAuthorizeReadHook + Read func(acl.Authorizer, *acl.AuthorizerContext, *pbresource.ID, *pbresource.Resource) error // Write is used to authorize Write and Delete RPCs. // // If it is omitted, `operator:write` permission is assumed. - Write ACLAuthorizeWriteHook + Write func(acl.Authorizer, *acl.AuthorizerContext, *pbresource.Resource) error // List is used to authorize List RPCs. // // If it is omitted, we only filter the results using Read. - List ACLAuthorizeListHook + List func(acl.Authorizer, *acl.AuthorizerContext) error } // Resource type registry diff --git a/internal/resource/resource.go b/internal/resource/resource.go deleted file mode 100644 index 2f3a7a05ca2c2..0000000000000 --- a/internal/resource/resource.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource - -import ( - "fmt" - "strings" - - mapset "github.com/deckarep/golang-set/v2" - - "github.com/hashicorp/consul/agent/dns" - "github.com/hashicorp/consul/proto-public/pbresource" -) - -// MaxNameLength is the maximum length of a resource name. -const MaxNameLength = 63 - -// DeletionTimestampKey is the key in a resource's metadata that stores the timestamp -// when a resource was marked for deletion. This only applies to resources with finalizers. -const DeletionTimestampKey = "deletionTimestamp" - -// FinalizerKey is the key in resource's metadata that stores the whitespace separated -// list of finalizers. -const FinalizerKey = "finalizers" - -// ValidateName returns an error a name is not a valid resource name. -// The error will contain reference to what constitutes a valid resource name. -func ValidateName(name string) error { - if !dns.IsValidLabel(name) || strings.ToLower(name) != name || len(name) > MaxNameLength { - return fmt.Errorf("a resource name must consist of lower case alphanumeric characters or '-', must start and end with an alphanumeric character and be less than %d characters, got: %q", MaxNameLength+1, name) - } - return nil -} - -// IsMarkedForDeletion returns true if a resource has been marked for deletion, -// false otherwise. -func IsMarkedForDeletion(res *pbresource.Resource) bool { - if res.Metadata == nil { - return false - } - _, ok := res.Metadata[DeletionTimestampKey] - return ok -} - -// HasFinalizers returns true if a resource has one or more finalizers, false otherwise. -func HasFinalizers(res *pbresource.Resource) bool { - return GetFinalizers(res).Cardinality() >= 1 -} - -// HasFinalizer returns true if a resource has a given finalizers, false otherwise. -func HasFinalizer(res *pbresource.Resource, finalizer string) bool { - return GetFinalizers(res).Contains(finalizer) -} - -// AddFinalizer adds a finalizer to the given resource. -func AddFinalizer(res *pbresource.Resource, finalizer string) { - finalizerSet := GetFinalizers(res) - finalizerSet.Add(finalizer) - if res.Metadata == nil { - res.Metadata = map[string]string{} - } - res.Metadata[FinalizerKey] = strings.Join(finalizerSet.ToSlice(), " ") -} - -// RemoveFinalizer removes a finalizer from the given resource. -func RemoveFinalizer(res *pbresource.Resource, finalizer string) { - finalizerSet := GetFinalizers(res) - finalizerSet.Remove(finalizer) - if res.Metadata == nil { - res.Metadata = map[string]string{} - } - res.Metadata[FinalizerKey] = strings.Join(finalizerSet.ToSlice(), " ") -} - -// GetFinalizers returns the set of finalizers for the given resource. -func GetFinalizers(res *pbresource.Resource) mapset.Set[string] { - if res.Metadata == nil { - return mapset.NewSet[string]() - } - finalizers, ok := res.Metadata[FinalizerKey] - if !ok { - return mapset.NewSet[string]() - } - return mapset.NewSet[string](strings.Fields(finalizers)...) -} diff --git a/internal/resource/resource_test.go b/internal/resource/resource_test.go deleted file mode 100644 index 5057bd4cf8f36..0000000000000 --- a/internal/resource/resource_test.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package resource_test - -import ( - "testing" - - mapset "github.com/deckarep/golang-set/v2" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" -) - -func TestFinalizer(t *testing.T) { - t.Run("no finalizers", func(t *testing.T) { - res := rtest.Resource(pbtenancy.NamespaceType, "ns1").Build() - require.False(t, resource.HasFinalizers(res)) - require.False(t, resource.HasFinalizer(res, "finalizer1")) - require.Equal(t, mapset.NewSet[string](), resource.GetFinalizers(res)) - resource.RemoveFinalizer(res, "finalizer") - }) - - t.Run("add finalizer", func(t *testing.T) { - res := rtest.Resource(pbtenancy.NamespaceType, "ns1").Build() - resource.AddFinalizer(res, "finalizer1") - require.True(t, resource.HasFinalizers(res)) - require.True(t, resource.HasFinalizer(res, "finalizer1")) - require.False(t, resource.HasFinalizer(res, "finalizer2")) - require.Equal(t, mapset.NewSet[string]("finalizer1"), resource.GetFinalizers(res)) - - // add duplicate -> noop - resource.AddFinalizer(res, "finalizer1") - require.Equal(t, mapset.NewSet[string]("finalizer1"), resource.GetFinalizers(res)) - }) - - t.Run("remove finalizer", func(t *testing.T) { - res := rtest.Resource(pbtenancy.NamespaceType, "ns1").Build() - resource.AddFinalizer(res, "finalizer1") - resource.AddFinalizer(res, "finalizer2") - resource.RemoveFinalizer(res, "finalizer1") - require.False(t, resource.HasFinalizer(res, "finalizer1")) - require.True(t, resource.HasFinalizer(res, "finalizer2")) - require.Equal(t, mapset.NewSet[string]("finalizer2"), resource.GetFinalizers(res)) - - // remove non-existent -> noop - resource.RemoveFinalizer(res, "finalizer3") - require.Equal(t, mapset.NewSet[string]("finalizer2"), resource.GetFinalizers(res)) - }) - -} diff --git a/internal/resource/resourcetest/builder.go b/internal/resource/resourcetest/builder.go index 3de836a71db34..423bd66aaa228 100644 --- a/internal/resource/resourcetest/builder.go +++ b/internal/resource/resourcetest/builder.go @@ -178,7 +178,7 @@ func (b *resourceBuilder) Write(t T, client pbresource.ResourceServiceClient) *p id := proto.Clone(rsp.Resource.Id).(*pbresource.ID) id.Uid = "" t.Cleanup(func() { - rtestClient.MustDelete(t, id) + rtestClient.CleanupDelete(t, id) }) } diff --git a/internal/resource/resourcetest/client.go b/internal/resource/resourcetest/client.go index 94bcd604265ed..a9ad08f5358de 100644 --- a/internal/resource/resourcetest/client.go +++ b/internal/resource/resourcetest/client.go @@ -5,12 +5,14 @@ package resourcetest import ( "context" + "flag" "fmt" "math/rand" "time" "github.com/stretchr/testify/require" "golang.org/x/exp/slices" + "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" @@ -21,25 +23,67 @@ import ( "github.com/hashicorp/consul/sdk/testutil/retry" ) +type ClientOption func(*Client) + +func WithRNGSeed(seed int64) ClientOption { + return func(c *Client) { + c.rng = rand.New(rand.NewSource(seed)) + } +} + +func WithRequestDelay(minMilliseconds int, maxMilliseconds int) ClientOption { + return func(c *Client) { + + min := minMilliseconds + max := maxMilliseconds + if max < min { + min = maxMilliseconds + max = minMilliseconds + } + c.requestDelayMin = min + c.requestDelayMax = max + } +} + +func WithACLToken(token string) ClientOption { + return func(c *Client) { + c.token = token + } +} + type Client struct { pbresource.ResourceServiceClient timeout time.Duration wait time.Duration token string -} -func NewClient(client pbresource.ResourceServiceClient) *Client { - return NewClientWithACLToken(client, "") + rng *rand.Rand + + requestDelayMin int + requestDelayMax int } -func NewClientWithACLToken(client pbresource.ResourceServiceClient, token string) *Client { - return &Client{ +func NewClient(client pbresource.ResourceServiceClient, opts ...ClientOption) *Client { + c := &Client{ ResourceServiceClient: client, timeout: 7 * time.Second, wait: 25 * time.Millisecond, - token: token, + rng: rand.New(rand.NewSource(time.Now().UnixNano())), + // arbitrary write delays are opt-in only + requestDelayMin: 0, + requestDelayMax: 0, } + + for _, opt := range opts { + opt(c) + } + + return c +} + +func NewClientWithACLToken(client pbresource.ResourceServiceClient, token string) *Client { + return NewClient(client, WithACLToken(token)) } func (client *Client) SetRetryerConfig(timeout time.Duration, wait time.Duration) { @@ -60,7 +104,7 @@ func (client *Client) PublishResources(t T, resources []*pbresource.Resource) { // controllers should eventually converge on the desired state. The exception to this // is that you cannot insert resources with owner refs before the resource they are // owned by or insert a resource into a non-default tenant before that tenant exists. - rand.Shuffle(len(resources), func(i, j int) { + client.rng.Shuffle(len(resources), func(i, j int) { temp := resources[i] resources[i] = resources[j] resources[j] = temp @@ -97,7 +141,7 @@ func (client *Client) PublishResources(t T, resources []*pbresource.Resource) { id := rsp.Resource.Id t.Cleanup(func() { - client.MustDelete(t, id) + client.CleanupDelete(t, id) }) // track the number of resources published @@ -119,6 +163,11 @@ func (client *Client) PublishResources(t T, resources []*pbresource.Resource) { require.Empty(t, resources, "Could not publish all resources - some resources have invalid owner references") } +func (client *Client) Write(ctx context.Context, in *pbresource.WriteRequest, opts ...grpc.CallOption) (*pbresource.WriteResponse, error) { + client.delayRequest() + return client.ResourceServiceClient.Write(ctx, in, opts...) +} + func (client *Client) Context(t T) context.Context { ctx := testutil.TestContext(t) @@ -231,17 +280,6 @@ func (client *Client) WaitForStatusCondition(t T, id *pbresource.ID, statusKey s return res } -func (client *Client) WaitForStatusConditionAnyGen(t T, id *pbresource.ID, statusKey string, condition *pbresource.Condition) *pbresource.Resource { - t.Helper() - - var res *pbresource.Resource - client.retry(t, func(r *retry.R) { - res = client.RequireStatusCondition(r, id, statusKey, condition) - }) - - return res -} - func (client *Client) WaitForStatusConditions(t T, id *pbresource.ID, statusKey string, conditions ...*pbresource.Condition) *pbresource.Resource { t.Helper() @@ -291,11 +329,32 @@ func (client *Client) ResolveResourceID(t T, id *pbresource.ID) *pbresource.ID { return client.RequireResourceExists(t, id).Id } +// MustDelete will delete a resource by its id, retrying if necessary and fail the test +// if it cannot delete it within the timeout. The clients request delay settings are +// taken into account with this operation. func (client *Client) MustDelete(t T, id *pbresource.ID) { + t.Helper() + client.retryDelete(t, id, true) +} + +// CleanupDelete will perform the same operations as MustDelete to ensure the resource is +// deleted. The clients request delay settings are ignored for this operation and it is +// assumed this will only be called in the context of test Cleanup routines where we +// are no longer testing that a controller eventually converges on some values in response +// to the delete. +func (client *Client) CleanupDelete(t T, id *pbresource.ID) { + t.Helper() + client.retryDelete(t, id, true) +} + +func (client *Client) retryDelete(t T, id *pbresource.ID, shouldDelay bool) { t.Helper() ctx := client.Context(t) client.retry(t, func(r *retry.R) { + if shouldDelay { + client.delayRequest() + } _, err := client.Delete(ctx, &pbresource.DeleteRequest{Id: id}) if status.Code(err) == codes.NotFound { return @@ -311,3 +370,53 @@ func (client *Client) MustDelete(t T, id *pbresource.ID) { require.NoError(r, err) }) } + +func (client *Client) delayRequest() { + if client.requestDelayMin == 0 && client.requestDelayMax == 0 { + return + } + + var delay time.Duration + if client.requestDelayMin == client.requestDelayMax { + delay = time.Duration(client.requestDelayMin) * time.Millisecond + } else { + delay = time.Duration(client.rng.Intn(client.requestDelayMax-client.requestDelayMin)+client.requestDelayMin) * time.Millisecond + } + time.Sleep(delay) +} + +type CLIOptions struct { + minRequestDelay int + maxRequestDelay int + seed int64 +} + +type CLIOptionT interface { + Helper() + Logf(string, ...any) +} + +func (o *CLIOptions) ClientOptions(t CLIOptionT) []ClientOption { + t.Helper() + t.Logf("Using %d for the random number generator seed. Pass -rng-seed= to overwrite the time based seed", o.seed) + t.Logf("Using random request delays between %dms and %dms. Use -min-request-delay= or -max-request-delay= to override the defaults", o.minRequestDelay, o.maxRequestDelay) + + return []ClientOption{ + WithRNGSeed(o.seed), + WithRequestDelay(o.minRequestDelay, o.maxRequestDelay), + } +} + +func ConfigureTestCLIFlags() *CLIOptions { + opts := &CLIOptions{ + minRequestDelay: 0, + maxRequestDelay: 0, + seed: time.Now().UnixNano(), + } + + flag.Int64Var(&opts.seed, "rng-seed", opts.seed, "Seed to use for pseudo-random-number-generators") + flag.IntVar(&opts.minRequestDelay, "min-request-delay", 10, "Minimum delay before performing a resource write (milliseconds: default=10)") + flag.IntVar(&opts.maxRequestDelay, "max-request-delay", 50, "Maximum delay before performing a resource write (milliseconds: default=50)") + + return opts +} diff --git a/internal/resource/resourcetest/tenancy.go b/internal/resource/resourcetest/tenancy.go index d05306e8f2951..5f5c0525b6f43 100644 --- a/internal/resource/resourcetest/tenancy.go +++ b/internal/resource/resourcetest/tenancy.go @@ -7,24 +7,10 @@ import ( "strings" "testing" - "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/proto-public/pbresource" ) -// TestTenancies returns a list of tenancies which represent -// the namespace and partition combinations that can be used in unit tests -func TestTenancies() []*pbresource.Tenancy { - isEnterprise := (structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default") - - tenancies := []*pbresource.Tenancy{Tenancy("default.default")} - if isEnterprise { - tenancies = append(tenancies, Tenancy("default.bar"), Tenancy("foo.default"), Tenancy("foo.bar")) - } - - return tenancies -} - // Tenancy constructs a pbresource.Tenancy from a concise string representation // suitable for use in unit tests. // diff --git a/internal/resource/tenancy.go b/internal/resource/tenancy.go index 597253aa8dc13..126e12413f6a8 100644 --- a/internal/resource/tenancy.go +++ b/internal/resource/tenancy.go @@ -5,6 +5,7 @@ package resource import ( "fmt" + "strings" "google.golang.org/protobuf/proto" @@ -24,6 +25,15 @@ const ( DefaultPeerName = "local" ) +// V2TenancyBridge is used by the resource service to access V2 implementations of +// partitions and namespaces. +type V2TenancyBridge struct { +} + +func NewV2TenancyBridge() TenancyBridge { + return &V2TenancyBridge{} +} + // Scope describes the tenancy scope of a resource. type Scope int @@ -52,6 +62,20 @@ func (s Scope) String() string { panic(fmt.Sprintf("string mapping missing for scope %v", int(s))) } +// Normalize lowercases the partition and namespace. +func Normalize(tenancy *pbresource.Tenancy) { + if tenancy == nil { + return + } + tenancy.Partition = strings.ToLower(tenancy.Partition) + tenancy.Namespace = strings.ToLower(tenancy.Namespace) + + // TODO(spatel): NET-5475 - Remove as part of peer_name moving to PeerTenancy + if tenancy.PeerName == "" { + tenancy.PeerName = DefaultPeerName + } +} + // DefaultClusteredTenancy returns the default tenancy for a cluster scoped resource. func DefaultClusteredTenancy() *pbresource.Tenancy { return &pbresource.Tenancy{ @@ -132,6 +156,7 @@ func defaultTenancy(itemTenancy, parentTenancy, scopeTenancy *pbresource.Tenancy if itemTenancy.PeerName == "" { itemTenancy.PeerName = DefaultPeerName } + Normalize(itemTenancy) if parentTenancy != nil { // Recursively normalize this tenancy as well. @@ -142,6 +167,7 @@ func defaultTenancy(itemTenancy, parentTenancy, scopeTenancy *pbresource.Tenancy if parentTenancy == nil { parentTenancy = scopeTenancy } + Normalize(parentTenancy) if !equalOrEmpty(itemTenancy.PeerName, DefaultPeerName) { panic("peering is not supported yet for resource tenancies") diff --git a/internal/tenancy/internal/bridge/tenancy_bridge_ce.go b/internal/resource/tenancy_bridge_ce.go similarity index 52% rename from internal/tenancy/internal/bridge/tenancy_bridge_ce.go rename to internal/resource/tenancy_bridge_ce.go index dcf4df663cc73..9f88c22361998 100644 --- a/internal/tenancy/internal/bridge/tenancy_bridge_ce.go +++ b/internal/resource/tenancy_bridge_ce.go @@ -3,7 +3,7 @@ //go:build !consulent -package bridge +package resource func (b *V2TenancyBridge) PartitionExists(partition string) (bool, error) { if partition == "default" { @@ -15,3 +15,14 @@ func (b *V2TenancyBridge) PartitionExists(partition string) (bool, error) { func (b *V2TenancyBridge) IsPartitionMarkedForDeletion(partition string) (bool, error) { return false, nil } + +func (b *V2TenancyBridge) NamespaceExists(partition, namespace string) (bool, error) { + if partition == "default" && namespace == "default" { + return true, nil + } + return false, nil +} + +func (b *V2TenancyBridge) IsNamespaceMarkedForDeletion(partition, namespace string) (bool, error) { + return false, nil +} diff --git a/internal/tenancy/exports.go b/internal/tenancy/exports.go index 18340ce039240..aadd7efb59beb 100644 --- a/internal/tenancy/exports.go +++ b/internal/tenancy/exports.go @@ -4,15 +4,21 @@ package tenancy import ( - "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/resource" - "github.com/hashicorp/consul/internal/tenancy/internal/bridge" - "github.com/hashicorp/consul/internal/tenancy/internal/controllers" "github.com/hashicorp/consul/internal/tenancy/internal/types" ) -type ( - V2TenancyBridge = bridge.V2TenancyBridge +var ( + // API Group Information + + APIGroup = types.GroupName + VersionV1Alpha1 = types.VersionV1Alpha1 + CurrentVersion = types.CurrentVersion + + // Resource Kind Names. + + NamespaceKind = types.NamespaceKind + NamespaceV1Alpha1Type = types.NamespaceV1Alpha1Type ) // RegisterTypes adds all resource types within the "tenancy" API group @@ -20,15 +26,3 @@ type ( func RegisterTypes(r resource.Registry) { types.Register(r) } - -// RegisterControllers registers controllers for the tenancy types with -// the given controller manager. -func RegisterControllers(mgr *controller.Manager, deps Dependencies) { - controllers.Register(mgr, deps) -} - -func NewV2TenancyBridge() *V2TenancyBridge { - return bridge.NewV2TenancyBridge() -} - -type Dependencies = controllers.Dependencies diff --git a/internal/tenancy/internal/bridge/tenancy_bridge.go b/internal/tenancy/internal/bridge/tenancy_bridge.go deleted file mode 100644 index db6a4dd53a176..0000000000000 --- a/internal/tenancy/internal/bridge/tenancy_bridge.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package bridge - -import ( - "context" - - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" -) - -// V2TenancyBridge is used by the resource service to access V2 implementations of -// partitions and namespaces. -type V2TenancyBridge struct { - client pbresource.ResourceServiceClient -} - -// WithClient inject a ResourceServiceClient in the V2TenancyBridge. -// This is needed to break a circular dependency between -// the ResourceServiceServer, ResourceServiceClient and the TenancyBridge -func (b *V2TenancyBridge) WithClient(client pbresource.ResourceServiceClient) *V2TenancyBridge { - b.client = client - return b -} - -func NewV2TenancyBridge() *V2TenancyBridge { - return &V2TenancyBridge{} -} - -func (b *V2TenancyBridge) NamespaceExists(partition, namespace string) (bool, error) { - read, err := b.client.Read(context.Background(), &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Name: namespace, - Tenancy: &pbresource.Tenancy{ - Partition: partition, - }, - Type: pbtenancy.NamespaceType, - }, - }) - return read != nil && read.Resource != nil, err -} - -func (b *V2TenancyBridge) IsNamespaceMarkedForDeletion(partition, namespace string) (bool, error) { - read, err := b.client.Read(context.Background(), &pbresource.ReadRequest{ - Id: &pbresource.ID{ - Name: namespace, - Tenancy: &pbresource.Tenancy{ - Partition: partition, - }, - Type: pbtenancy.NamespaceType, - }, - }) - return read.Resource != nil, err -} diff --git a/internal/tenancy/internal/controllers/register.go b/internal/tenancy/internal/controllers/register.go deleted file mode 100644 index 94b4255baeb57..0000000000000 --- a/internal/tenancy/internal/controllers/register.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package controllers - -import ( - "github.com/hashicorp/consul/internal/resource" -) - -type Dependencies struct { - Registry resource.Registry -} diff --git a/internal/tenancy/internal/controllers/register_ce.go b/internal/tenancy/internal/controllers/register_ce.go deleted file mode 100644 index a1623e5e95b52..0000000000000 --- a/internal/tenancy/internal/controllers/register_ce.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -//go:build !consulent - -package controllers - -import ( - "github.com/hashicorp/consul/internal/controller" -) - -func Register(mgr *controller.Manager, deps Dependencies) { - //mgr.Register(namespace.NamespaceController()) -} diff --git a/internal/tenancy/internal/types/namespace.go b/internal/tenancy/internal/types/namespace.go index c45b405e8b325..4bc95d1505f7d 100644 --- a/internal/tenancy/internal/types/namespace.go +++ b/internal/tenancy/internal/types/namespace.go @@ -5,26 +5,44 @@ package types import ( "fmt" - "strings" - "github.com/hashicorp/consul/agent/dns" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" + tenancyv1alpha1 "github.com/hashicorp/consul/proto-public/pbtenancy/v1alpha1" + "strings" +) + +const ( + NamespaceKind = "Namespace" +) + +var ( + NamespaceV1Alpha1Type = &pbresource.Type{ + Group: GroupName, + GroupVersion: VersionV1Alpha1, + Kind: NamespaceKind, + } + NamespaceType = NamespaceV1Alpha1Type ) func RegisterNamespace(r resource.Registry) { r.Register(resource.Registration{ - Type: pbtenancy.NamespaceType, - Proto: &pbtenancy.Namespace{}, + Type: NamespaceV1Alpha1Type, + Proto: &tenancyv1alpha1.Namespace{}, Scope: resource.ScopePartition, Validate: ValidateNamespace, + Mutate: MutateNamespace, // ACLs: TODO }) } +func MutateNamespace(res *pbresource.Resource) error { + res.Id.Name = strings.ToLower(res.Id.Name) + return nil +} + func ValidateNamespace(res *pbresource.Resource) error { - var ns pbtenancy.Namespace + var ns tenancyv1alpha1.Namespace if err := res.Data.UnmarshalTo(&ns); err != nil { return resource.NewErrDataParse(&ns, err) diff --git a/internal/tenancy/internal/types/types_test.go b/internal/tenancy/internal/types/namespace_test.go similarity index 54% rename from internal/tenancy/internal/types/types_test.go rename to internal/tenancy/internal/types/namespace_test.go index df22b71f13a27..b64f86d5212bc 100644 --- a/internal/tenancy/internal/types/types_test.go +++ b/internal/tenancy/internal/types/namespace_test.go @@ -4,6 +4,14 @@ package types import ( + "context" + "errors" + svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" + rtest "github.com/hashicorp/consul/internal/resource/resourcetest" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto/private/prototest" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "testing" "github.com/stretchr/testify/require" @@ -11,15 +19,14 @@ import ( "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/consul/internal/resource" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" + pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v1alpha1" ) func createNamespaceResource(t *testing.T, data protoreflect.ProtoMessage) *pbresource.Resource { res := &pbresource.Resource{ Id: &pbresource.ID{ - Type: pbtenancy.NamespaceType, + Type: NamespaceV1Alpha1Type, Tenancy: resource.DefaultPartitionedTenancy(), Name: "ns1234", }, @@ -86,6 +93,28 @@ func TestValidateNamespace_ParseError(t *testing.T) { require.ErrorAs(t, err, &resource.ErrDataParse{}) } +func TestMutateNamespace(t *testing.T) { + tests := []struct { + name string + namespaceName string + expectedName string + err error + }{ + {"lower", "lower", "lower", nil}, + {"mixed", "MiXeD", "mixed", nil}, + {"upper", "UPPER", "upper", nil}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + res := &pbresource.Resource{Id: &pbresource.ID{Name: tt.namespaceName}} + if err := MutateNamespace(res); !errors.Is(err, tt.err) { + t.Errorf("MutateNamespace() error = %v", err) + } + require.Equal(t, res.Id.Name, tt.expectedName) + }) + } +} + func TestValidateNamespace(t *testing.T) { tests := []struct { name string @@ -114,6 +143,64 @@ func TestValidateNamespace(t *testing.T) { } } +func TestRead_Success(t *testing.T) { + client := svctest.RunResourceService(t, Register) + client = rtest.NewClient(client) + + res := rtest.Resource(NamespaceType, "ns1"). + WithData(t, validNamespace()). + Write(t, client) + + readRsp, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) + require.NoError(t, err) + prototest.AssertDeepEqual(t, res.Id, readRsp.Resource.Id) +} + +func TestRead_NotFound(t *testing.T) { + client := svctest.RunResourceService(t, Register) + client = rtest.NewClient(client) + + res := rtest.Resource(NamespaceType, "ns1"). + WithData(t, validNamespace()).Build() + + _, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) + require.Error(t, err) + require.Equal(t, codes.NotFound.String(), status.Code(err).String()) +} + +func TestDelete_Success(t *testing.T) { + client := svctest.RunResourceService(t, Register) + client = rtest.NewClient(client) + + res := rtest.Resource(NamespaceType, "ns1"). + WithData(t, validNamespace()).Write(t, client) + + readRsp, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) + require.NoError(t, err) + prototest.AssertDeepEqual(t, res.Id, readRsp.Resource.Id) + + _, err = client.Delete(context.Background(), &pbresource.DeleteRequest{Id: res.Id}) + require.NoError(t, err) + + _, err = client.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) + require.Error(t, err) + require.Equal(t, codes.NotFound.String(), status.Code(err).String()) + +} + +func TestRead_MixedCases_Success(t *testing.T) { + client := svctest.RunResourceService(t, Register) + client = rtest.NewClient(client) + + res := rtest.Resource(NamespaceType, "nS1"). + WithData(t, validNamespace()).Write(t, client) + + readRsp, err := client.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) + require.NoError(t, err) + prototest.AssertDeepEqual(t, res.Id, readRsp.Resource.Id) + +} + func validNamespace() *pbtenancy.Namespace { return &pbtenancy.Namespace{ Description: "ns namespace", diff --git a/internal/tenancy/internal/types/types.go b/internal/tenancy/internal/types/types.go index 5955ade8a5d7b..be0a615153fd0 100644 --- a/internal/tenancy/internal/types/types.go +++ b/internal/tenancy/internal/types/types.go @@ -4,7 +4,7 @@ package types const ( - GroupName = "tenancy" - VersionV2Beta1 = "v2beta1" - CurrentVersion = VersionV2Beta1 + GroupName = "tenancy" + VersionV1Alpha1 = "v1alpha1" + CurrentVersion = VersionV1Alpha1 ) diff --git a/internal/tenancy/tenancytest/namespace_test.go b/internal/tenancy/tenancytest/namespace_test.go deleted file mode 100644 index e2461c254cd20..0000000000000 --- a/internal/tenancy/tenancytest/namespace_test.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package tenancytest - -import ( - "context" - "testing" - - "github.com/stretchr/testify/require" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - - svc "github.com/hashicorp/consul/agent/grpc-external/services/resource" - svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" - "github.com/hashicorp/consul/internal/resource" - rtest "github.com/hashicorp/consul/internal/resource/resourcetest" - "github.com/hashicorp/consul/internal/tenancy" - "github.com/hashicorp/consul/proto-public/pbresource" - pbtenancy "github.com/hashicorp/consul/proto-public/pbtenancy/v2beta1" - "github.com/hashicorp/consul/proto/private/prototest" -) - -func TestWriteNamespace_Success(t *testing.T) { - v2TenancyBridge := tenancy.NewV2TenancyBridge() - config := svc.Config{TenancyBridge: v2TenancyBridge, UseV2Tenancy: true} - client := svctest.RunResourceServiceWithConfig(t, config, tenancy.RegisterTypes) - cl := rtest.NewClient(client) - - res := rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithTenancy(resource.DefaultPartitionedTenancy()). - WithData(t, validNamespace()). - Build() - - writeRsp, err := cl.Write(context.Background(), &pbresource.WriteRequest{Resource: res}) - require.NoError(t, err) - prototest.AssertDeepEqual(t, res.Id.Type, writeRsp.Resource.Id.Type) - prototest.AssertDeepEqual(t, res.Id.Tenancy, writeRsp.Resource.Id.Tenancy) - prototest.AssertDeepEqual(t, res.Id.Name, writeRsp.Resource.Id.Name) - prototest.AssertDeepEqual(t, res.Data, writeRsp.Resource.Data) -} - -func TestReadNamespace_Success(t *testing.T) { - v2TenancyBridge := tenancy.NewV2TenancyBridge() - config := svc.Config{TenancyBridge: v2TenancyBridge, UseV2Tenancy: true} - client := svctest.RunResourceServiceWithConfig(t, config, tenancy.RegisterTypes) - cl := rtest.NewClient(client) - - res := rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithData(t, validNamespace()). - Write(t, cl) - - cases := []struct { - name string - resource *pbresource.Resource - errMsg string - }{ - { - name: "read namespace", - resource: rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithData(t, validNamespace()). - Build(), - }, - } - - for _, tc := range cases { - t.Run(tc.name, func(t *testing.T) { - readRsp, err := cl.Read(context.Background(), &pbresource.ReadRequest{Id: tc.resource.Id}) - require.NoError(t, err) - prototest.AssertDeepEqual(t, res.Id, readRsp.Resource.Id) - prototest.AssertDeepEqual(t, res.Data, readRsp.Resource.Data) - }) - } -} - -func TestDeleteNamespace_Success(t *testing.T) { - v2TenancyBridge := tenancy.NewV2TenancyBridge() - config := svc.Config{TenancyBridge: v2TenancyBridge, UseV2Tenancy: true} - client := svctest.RunResourceServiceWithConfig(t, config, tenancy.RegisterTypes) - cl := rtest.NewClient(client) - - res := rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithData(t, validNamespace()).Write(t, cl) - - readRsp, err := cl.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) - require.NoError(t, err) - prototest.AssertDeepEqual(t, res.Id, readRsp.Resource.Id) - - _, err = cl.Delete(context.Background(), &pbresource.DeleteRequest{Id: res.Id}) - require.NoError(t, err) - - _, err = cl.Read(context.Background(), &pbresource.ReadRequest{Id: res.Id}) - require.Error(t, err) - require.Equal(t, codes.NotFound.String(), status.Code(err).String()) - -} - -func TestListNamespace_Success(t *testing.T) { - v2TenancyBridge := tenancy.NewV2TenancyBridge() - config := svc.Config{TenancyBridge: v2TenancyBridge, UseV2Tenancy: true} - client := svctest.RunResourceServiceWithConfig(t, config, tenancy.RegisterTypes) - cl := rtest.NewClient(client) - - res := rtest.Resource(pbtenancy.NamespaceType, "ns1"). - WithData(t, validNamespace()).Write(t, cl) - - require.NotNil(t, res) - res = rtest.Resource(pbtenancy.NamespaceType, "ns2"). - WithData(t, validNamespace()).Write(t, cl) - - require.NotNil(t, res) - - listRsp, err := cl.List(context.Background(), &pbresource.ListRequest{Type: pbtenancy.NamespaceType, Tenancy: resource.DefaultPartitionedTenancy()}) - require.NoError(t, err) - require.Len(t, listRsp.Resources, 3) - names := []string{ - listRsp.Resources[0].Id.Name, - listRsp.Resources[1].Id.Name, - listRsp.Resources[2].Id.Name, - } - require.Contains(t, names, "default") - require.Contains(t, names, "ns1") - require.Contains(t, names, "ns2") -} - -func validNamespace() *pbtenancy.Namespace { - return &pbtenancy.Namespace{ - Description: "ns namespace", - } -} diff --git a/proto-public/pbcatalog/v2beta1/failover_policy.pb.go b/proto-public/pbcatalog/v2beta1/failover_policy.pb.go index 844e9e7a0af71..58e70174a1e86 100644 --- a/proto-public/pbcatalog/v2beta1/failover_policy.pb.go +++ b/proto-public/pbcatalog/v2beta1/failover_policy.pb.go @@ -24,8 +24,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// +kubebuilder:validation:Enum=FAILOVER_MODE_UNSPECIFIED;FAILOVER_MODE_SEQUENTIAL;FAILOVER_MODE_ORDER_BY_LOCALITY -// +kubebuilder:validation:Type=string type FailoverMode int32 const ( diff --git a/proto-public/pbcatalog/v2beta1/failover_policy.proto b/proto-public/pbcatalog/v2beta1/failover_policy.proto index abbeb46a3ae8b..dec86807f7543 100644 --- a/proto-public/pbcatalog/v2beta1/failover_policy.proto +++ b/proto-public/pbcatalog/v2beta1/failover_policy.proto @@ -43,8 +43,6 @@ message FailoverDestination { string datacenter = 3; } -// +kubebuilder:validation:Enum=FAILOVER_MODE_UNSPECIFIED;FAILOVER_MODE_SEQUENTIAL;FAILOVER_MODE_ORDER_BY_LOCALITY -// +kubebuilder:validation:Type=string enum FailoverMode { FAILOVER_MODE_UNSPECIFIED = 0; FAILOVER_MODE_SEQUENTIAL = 1; diff --git a/proto-public/pbcatalog/v2beta1/health.pb.go b/proto-public/pbcatalog/v2beta1/health.pb.go index 154a183831b21..93b045b017fde 100644 --- a/proto-public/pbcatalog/v2beta1/health.pb.go +++ b/proto-public/pbcatalog/v2beta1/health.pb.go @@ -25,8 +25,6 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// +kubebuilder:validation:Enum=HEALTH_ANY;HEALTH_PASSING;HEALTH_WARNING;HEALTH_CRITICAL;HEALTH_MAINTENANCE -// +kubebuilder:validation:Type=string type Health int32 const ( diff --git a/proto-public/pbcatalog/v2beta1/health.proto b/proto-public/pbcatalog/v2beta1/health.proto index 29b4f5bf4cdd8..316c58d5d197f 100644 --- a/proto-public/pbcatalog/v2beta1/health.proto +++ b/proto-public/pbcatalog/v2beta1/health.proto @@ -23,8 +23,6 @@ message HealthStatus { string output = 4; } -// +kubebuilder:validation:Enum=HEALTH_ANY;HEALTH_PASSING;HEALTH_WARNING;HEALTH_CRITICAL;HEALTH_MAINTENANCE -// +kubebuilder:validation:Type=string enum Health { // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX HEALTH_ANY = 0; diff --git a/proto-public/pbmesh/v2beta1/mesh_gateway.pb.binary.go b/proto-public/pbmesh/v2beta1/mesh_gateway.pb.binary.go deleted file mode 100644 index 7cd36afdb3c06..0000000000000 --- a/proto-public/pbmesh/v2beta1/mesh_gateway.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmesh/v2beta1/mesh_gateway.proto - -package meshv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *MeshGateway) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *MeshGateway) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmesh/v2beta1/mesh_gateway.pb.go b/proto-public/pbmesh/v2beta1/mesh_gateway.pb.go deleted file mode 100644 index 7eb247ded34a4..0000000000000 --- a/proto-public/pbmesh/v2beta1/mesh_gateway.pb.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmesh/v2beta1/mesh_gateway.proto - -package meshv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type MeshGateway struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *MeshGateway) Reset() { - *x = MeshGateway{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmesh_v2beta1_mesh_gateway_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MeshGateway) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MeshGateway) ProtoMessage() {} - -func (x *MeshGateway) ProtoReflect() protoreflect.Message { - mi := &file_pbmesh_v2beta1_mesh_gateway_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MeshGateway.ProtoReflect.Descriptor instead. -func (*MeshGateway) Descriptor() ([]byte, []int) { - return file_pbmesh_v2beta1_mesh_gateway_proto_rawDescGZIP(), []int{0} -} - -var File_pbmesh_v2beta1_mesh_gateway_proto protoreflect.FileDescriptor - -var file_pbmesh_v2beta1_mesh_gateway_proto_rawDesc = []byte{ - 0x0a, 0x21, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2f, 0x6d, 0x65, 0x73, 0x68, 0x5f, 0x67, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x1d, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x22, 0x0d, 0x0a, 0x0b, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, - 0x79, 0x42, 0x91, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x10, 0x4d, 0x65, 0x73, 0x68, 0x47, 0x61, 0x74, - 0x65, 0x77, 0x61, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, - 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, 0x65, 0x73, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, 0x56, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmesh_v2beta1_mesh_gateway_proto_rawDescOnce sync.Once - file_pbmesh_v2beta1_mesh_gateway_proto_rawDescData = file_pbmesh_v2beta1_mesh_gateway_proto_rawDesc -) - -func file_pbmesh_v2beta1_mesh_gateway_proto_rawDescGZIP() []byte { - file_pbmesh_v2beta1_mesh_gateway_proto_rawDescOnce.Do(func() { - file_pbmesh_v2beta1_mesh_gateway_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_mesh_gateway_proto_rawDescData) - }) - return file_pbmesh_v2beta1_mesh_gateway_proto_rawDescData -} - -var file_pbmesh_v2beta1_mesh_gateway_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmesh_v2beta1_mesh_gateway_proto_goTypes = []interface{}{ - (*MeshGateway)(nil), // 0: hashicorp.consul.mesh.v2beta1.MeshGateway -} -var file_pbmesh_v2beta1_mesh_gateway_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbmesh_v2beta1_mesh_gateway_proto_init() } -func file_pbmesh_v2beta1_mesh_gateway_proto_init() { - if File_pbmesh_v2beta1_mesh_gateway_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmesh_v2beta1_mesh_gateway_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MeshGateway); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmesh_v2beta1_mesh_gateway_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmesh_v2beta1_mesh_gateway_proto_goTypes, - DependencyIndexes: file_pbmesh_v2beta1_mesh_gateway_proto_depIdxs, - MessageInfos: file_pbmesh_v2beta1_mesh_gateway_proto_msgTypes, - }.Build() - File_pbmesh_v2beta1_mesh_gateway_proto = out.File - file_pbmesh_v2beta1_mesh_gateway_proto_rawDesc = nil - file_pbmesh_v2beta1_mesh_gateway_proto_goTypes = nil - file_pbmesh_v2beta1_mesh_gateway_proto_depIdxs = nil -} diff --git a/proto-public/pbmesh/v2beta1/mesh_gateway.proto b/proto-public/pbmesh/v2beta1/mesh_gateway.proto deleted file mode 100644 index 1d976d7e22a30..0000000000000 --- a/proto-public/pbmesh/v2beta1/mesh_gateway.proto +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -syntax = "proto3"; - -package hashicorp.consul.mesh.v2beta1; - -message MeshGateway {} diff --git a/proto-public/pbmesh/v2beta1/mesh_gateway_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/mesh_gateway_deepcopy.gen.go deleted file mode 100644 index b14ad33a815a3..0000000000000 --- a/proto-public/pbmesh/v2beta1/mesh_gateway_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package meshv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using MeshGateway within kubernetes types, where deepcopy-gen is used. -func (in *MeshGateway) DeepCopyInto(out *MeshGateway) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshGateway. Required by controller-gen. -func (in *MeshGateway) DeepCopy() *MeshGateway { - if in == nil { - return nil - } - out := new(MeshGateway) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new MeshGateway. Required by controller-gen. -func (in *MeshGateway) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmesh/v2beta1/mesh_gateway_json.gen.go b/proto-public/pbmesh/v2beta1/mesh_gateway_json.gen.go deleted file mode 100644 index 548da69f08cdb..0000000000000 --- a/proto-public/pbmesh/v2beta1/mesh_gateway_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package meshv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for MeshGateway -func (this *MeshGateway) MarshalJSON() ([]byte, error) { - str, err := MeshGatewayMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for MeshGateway -func (this *MeshGateway) UnmarshalJSON(b []byte) error { - return MeshGatewayUnmarshaler.Unmarshal(b, this) -} - -var ( - MeshGatewayMarshaler = &protojson.MarshalOptions{} - MeshGatewayUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.binary.go b/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.binary.go deleted file mode 100644 index f5b389089f42d..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.binary.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/computed_exported_services.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedExportedServices) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedExportedServices) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedExportedService) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedExportedService) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ComputedExportedServicesConsumer) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ComputedExportedServicesConsumer) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.go b/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.go deleted file mode 100644 index 11ebe79f9dc6f..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services.pb.go +++ /dev/null @@ -1,373 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/computed_exported_services.proto - -package multiclusterv2beta1 - -import ( - pbresource "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ComputedExportedServices struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Consumers []*ComputedExportedService `protobuf:"bytes,1,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *ComputedExportedServices) Reset() { - *x = ComputedExportedServices{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedExportedServices) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedExportedServices) ProtoMessage() {} - -func (x *ComputedExportedServices) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedExportedServices.ProtoReflect.Descriptor instead. -func (*ComputedExportedServices) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescGZIP(), []int{0} -} - -func (x *ComputedExportedServices) GetConsumers() []*ComputedExportedService { - if x != nil { - return x.Consumers - } - return nil -} - -type ComputedExportedService struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - TargetRef *pbresource.Reference `protobuf:"bytes,1,opt,name=target_ref,json=targetRef,proto3" json:"target_ref,omitempty"` - Consumers []*ComputedExportedServicesConsumer `protobuf:"bytes,2,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *ComputedExportedService) Reset() { - *x = ComputedExportedService{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedExportedService) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedExportedService) ProtoMessage() {} - -func (x *ComputedExportedService) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedExportedService.ProtoReflect.Descriptor instead. -func (*ComputedExportedService) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescGZIP(), []int{1} -} - -func (x *ComputedExportedService) GetTargetRef() *pbresource.Reference { - if x != nil { - return x.TargetRef - } - return nil -} - -func (x *ComputedExportedService) GetConsumers() []*ComputedExportedServicesConsumer { - if x != nil { - return x.Consumers - } - return nil -} - -type ComputedExportedServicesConsumer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // no sameness group - // - // Types that are assignable to ConsumerTenancy: - // - // *ComputedExportedServicesConsumer_Peer - // *ComputedExportedServicesConsumer_Partition - ConsumerTenancy isComputedExportedServicesConsumer_ConsumerTenancy `protobuf_oneof:"consumer_tenancy"` -} - -func (x *ComputedExportedServicesConsumer) Reset() { - *x = ComputedExportedServicesConsumer{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ComputedExportedServicesConsumer) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ComputedExportedServicesConsumer) ProtoMessage() {} - -func (x *ComputedExportedServicesConsumer) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ComputedExportedServicesConsumer.ProtoReflect.Descriptor instead. -func (*ComputedExportedServicesConsumer) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescGZIP(), []int{2} -} - -func (m *ComputedExportedServicesConsumer) GetConsumerTenancy() isComputedExportedServicesConsumer_ConsumerTenancy { - if m != nil { - return m.ConsumerTenancy - } - return nil -} - -func (x *ComputedExportedServicesConsumer) GetPeer() string { - if x, ok := x.GetConsumerTenancy().(*ComputedExportedServicesConsumer_Peer); ok { - return x.Peer - } - return "" -} - -func (x *ComputedExportedServicesConsumer) GetPartition() string { - if x, ok := x.GetConsumerTenancy().(*ComputedExportedServicesConsumer_Partition); ok { - return x.Partition - } - return "" -} - -type isComputedExportedServicesConsumer_ConsumerTenancy interface { - isComputedExportedServicesConsumer_ConsumerTenancy() -} - -type ComputedExportedServicesConsumer_Peer struct { - Peer string `protobuf:"bytes,3,opt,name=peer,proto3,oneof"` -} - -type ComputedExportedServicesConsumer_Partition struct { - Partition string `protobuf:"bytes,4,opt,name=partition,proto3,oneof"` -} - -func (*ComputedExportedServicesConsumer_Peer) isComputedExportedServicesConsumer_ConsumerTenancy() {} - -func (*ComputedExportedServicesConsumer_Partition) isComputedExportedServicesConsumer_ConsumerTenancy() { -} - -var File_pbmulticluster_v2beta1_computed_exported_services_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDesc = []byte{ - 0x0a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x64, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, - 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x80, 0x01, 0x0a, 0x18, 0x43, 0x6f, - 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x5c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x22, 0xc5, 0x01, 0x0a, - 0x17, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x43, 0x0a, 0x0a, 0x74, 0x61, 0x72, 0x67, - 0x65, 0x74, 0x5f, 0x72, 0x65, 0x66, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, - 0x63, 0x65, 0x52, 0x09, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x65, 0x66, 0x12, 0x65, 0x0a, - 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x47, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, - 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x73, 0x22, 0x6c, 0x0a, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, - 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x1e, - 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x12, - 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6e, 0x61, 0x6e, - 0x63, 0x79, 0x42, 0xd6, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x42, 0x1d, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, - 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x3b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, - 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, - 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, - 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, - 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0xea, 0x02, 0x28, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var ( - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescData = file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_pbmulticluster_v2beta1_computed_exported_services_proto_goTypes = []interface{}{ - (*ComputedExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2beta1.ComputedExportedServices - (*ComputedExportedService)(nil), // 1: hashicorp.consul.multicluster.v2beta1.ComputedExportedService - (*ComputedExportedServicesConsumer)(nil), // 2: hashicorp.consul.multicluster.v2beta1.ComputedExportedServicesConsumer - (*pbresource.Reference)(nil), // 3: hashicorp.consul.resource.Reference -} -var file_pbmulticluster_v2beta1_computed_exported_services_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.multicluster.v2beta1.ComputedExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ComputedExportedService - 3, // 1: hashicorp.consul.multicluster.v2beta1.ComputedExportedService.target_ref:type_name -> hashicorp.consul.resource.Reference - 2, // 2: hashicorp.consul.multicluster.v2beta1.ComputedExportedService.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ComputedExportedServicesConsumer - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_computed_exported_services_proto_init() } -func file_pbmulticluster_v2beta1_computed_exported_services_proto_init() { - if File_pbmulticluster_v2beta1_computed_exported_services_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedExportedServices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedExportedService); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ComputedExportedServicesConsumer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes[2].OneofWrappers = []interface{}{ - (*ComputedExportedServicesConsumer_Peer)(nil), - (*ComputedExportedServicesConsumer_Partition)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_computed_exported_services_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_computed_exported_services_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_computed_exported_services_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_computed_exported_services_proto = out.File - file_pbmulticluster_v2beta1_computed_exported_services_proto_rawDesc = nil - file_pbmulticluster_v2beta1_computed_exported_services_proto_goTypes = nil - file_pbmulticluster_v2beta1_computed_exported_services_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services.proto b/proto-public/pbmulticluster/v2beta1/computed_exported_services.proto deleted file mode 100644 index b8a619558451c..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services.proto +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -import "pbresource/annotations.proto"; -import "pbresource/resource.proto"; - -message ComputedExportedServices { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_PARTITION}; - - repeated ComputedExportedService consumers = 1; -} - -message ComputedExportedService { - hashicorp.consul.resource.Reference target_ref = 1; - repeated ComputedExportedServicesConsumer consumers = 2; -} - -message ComputedExportedServicesConsumer { - // no sameness group - oneof consumer_tenancy { - string peer = 3; - string partition = 4; - } -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/computed_exported_services_deepcopy.gen.go deleted file mode 100644 index b50f35a20bd92..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services_deepcopy.gen.go +++ /dev/null @@ -1,69 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ComputedExportedServices within kubernetes types, where deepcopy-gen is used. -func (in *ComputedExportedServices) DeepCopyInto(out *ComputedExportedServices) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedServices. Required by controller-gen. -func (in *ComputedExportedServices) DeepCopy() *ComputedExportedServices { - if in == nil { - return nil - } - out := new(ComputedExportedServices) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedServices. Required by controller-gen. -func (in *ComputedExportedServices) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedExportedService within kubernetes types, where deepcopy-gen is used. -func (in *ComputedExportedService) DeepCopyInto(out *ComputedExportedService) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedService. Required by controller-gen. -func (in *ComputedExportedService) DeepCopy() *ComputedExportedService { - if in == nil { - return nil - } - out := new(ComputedExportedService) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedService. Required by controller-gen. -func (in *ComputedExportedService) DeepCopyInterface() interface{} { - return in.DeepCopy() -} - -// DeepCopyInto supports using ComputedExportedServicesConsumer within kubernetes types, where deepcopy-gen is used. -func (in *ComputedExportedServicesConsumer) DeepCopyInto(out *ComputedExportedServicesConsumer) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedServicesConsumer. Required by controller-gen. -func (in *ComputedExportedServicesConsumer) DeepCopy() *ComputedExportedServicesConsumer { - if in == nil { - return nil - } - out := new(ComputedExportedServicesConsumer) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExportedServicesConsumer. Required by controller-gen. -func (in *ComputedExportedServicesConsumer) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/computed_exported_services_json.gen.go b/proto-public/pbmulticluster/v2beta1/computed_exported_services_json.gen.go deleted file mode 100644 index 709a7e6ef6b20..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/computed_exported_services_json.gen.go +++ /dev/null @@ -1,44 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ComputedExportedServices -func (this *ComputedExportedServices) MarshalJSON() ([]byte, error) { - str, err := ComputedExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedExportedServices -func (this *ComputedExportedServices) UnmarshalJSON(b []byte) error { - return ComputedExportedServicesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedExportedService -func (this *ComputedExportedService) MarshalJSON() ([]byte, error) { - str, err := ComputedExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedExportedService -func (this *ComputedExportedService) UnmarshalJSON(b []byte) error { - return ComputedExportedServicesUnmarshaler.Unmarshal(b, this) -} - -// MarshalJSON is a custom marshaler for ComputedExportedServicesConsumer -func (this *ComputedExportedServicesConsumer) MarshalJSON() ([]byte, error) { - str, err := ComputedExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ComputedExportedServicesConsumer -func (this *ComputedExportedServicesConsumer) UnmarshalJSON(b []byte) error { - return ComputedExportedServicesUnmarshaler.Unmarshal(b, this) -} - -var ( - ComputedExportedServicesMarshaler = &protojson.MarshalOptions{} - ComputedExportedServicesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/exported_services.pb.binary.go b/proto-public/pbmulticluster/v2beta1/exported_services.pb.binary.go deleted file mode 100644 index 1530294804123..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/exported_services.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ExportedServices) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ExportedServices) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services.pb.go b/proto-public/pbmulticluster/v2beta1/exported_services.pb.go deleted file mode 100644 index 7e776c3a94c16..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services.pb.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/exported_services.proto - -package multiclusterv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ExportedServices struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Services []string `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"` - Consumers []*ExportedServicesConsumer `protobuf:"bytes,2,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *ExportedServices) Reset() { - *x = ExportedServices{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_exported_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExportedServices) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExportedServices) ProtoMessage() {} - -func (x *ExportedServices) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_exported_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExportedServices.ProtoReflect.Descriptor instead. -func (*ExportedServices) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_exported_services_proto_rawDescGZIP(), []int{0} -} - -func (x *ExportedServices) GetServices() []string { - if x != nil { - return x.Services - } - return nil -} - -func (x *ExportedServices) GetConsumers() []*ExportedServicesConsumer { - if x != nil { - return x.Consumers - } - return nil -} - -var File_pbmulticluster_v2beta1_exported_services_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_exported_services_proto_rawDesc = []byte{ - 0x0a, 0x2e, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, - 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, - 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, - 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x95, - 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, - 0x5d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, - 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, - 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x42, 0xce, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, - 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x42, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, - 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x28, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmulticluster_v2beta1_exported_services_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_exported_services_proto_rawDescData = file_pbmulticluster_v2beta1_exported_services_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_exported_services_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_exported_services_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_exported_services_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_exported_services_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmulticluster_v2beta1_exported_services_proto_goTypes = []interface{}{ - (*ExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2beta1.ExportedServices - (*ExportedServicesConsumer)(nil), // 1: hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer -} -var file_pbmulticluster_v2beta1_exported_services_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.multicluster.v2beta1.ExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_exported_services_proto_init() } -func file_pbmulticluster_v2beta1_exported_services_proto_init() { - if File_pbmulticluster_v2beta1_exported_services_proto != nil { - return - } - file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExportedServices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_exported_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_exported_services_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_exported_services_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_exported_services_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_exported_services_proto = out.File - file_pbmulticluster_v2beta1_exported_services_proto_rawDesc = nil - file_pbmulticluster_v2beta1_exported_services_proto_goTypes = nil - file_pbmulticluster_v2beta1_exported_services_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services.proto b/proto-public/pbmulticluster/v2beta1/exported_services.proto deleted file mode 100644 index 76cd98ad7a46f..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services.proto +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -import "pbmulticluster/v2beta1/exported_services_consumer.proto"; -import "pbresource/annotations.proto"; - -message ExportedServices { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - repeated string services = 1; - repeated ExportedServicesConsumer consumers = 2; -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.binary.go b/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.binary.go deleted file mode 100644 index 5f8eecd75158b..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/exported_services_consumer.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *ExportedServicesConsumer) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *ExportedServicesConsumer) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.go b/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.go deleted file mode 100644 index a254b81af0a63..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.pb.go +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/exported_services_consumer.proto - -package multiclusterv2beta1 - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type ExportedServicesConsumer struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to ConsumerTenancy: - // - // *ExportedServicesConsumer_Peer - // *ExportedServicesConsumer_Partition - // *ExportedServicesConsumer_SamenessGroup - ConsumerTenancy isExportedServicesConsumer_ConsumerTenancy `protobuf_oneof:"consumer_tenancy"` -} - -func (x *ExportedServicesConsumer) Reset() { - *x = ExportedServicesConsumer{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExportedServicesConsumer) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExportedServicesConsumer) ProtoMessage() {} - -func (x *ExportedServicesConsumer) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExportedServicesConsumer.ProtoReflect.Descriptor instead. -func (*ExportedServicesConsumer) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescGZIP(), []int{0} -} - -func (m *ExportedServicesConsumer) GetConsumerTenancy() isExportedServicesConsumer_ConsumerTenancy { - if m != nil { - return m.ConsumerTenancy - } - return nil -} - -func (x *ExportedServicesConsumer) GetPeer() string { - if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_Peer); ok { - return x.Peer - } - return "" -} - -func (x *ExportedServicesConsumer) GetPartition() string { - if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_Partition); ok { - return x.Partition - } - return "" -} - -func (x *ExportedServicesConsumer) GetSamenessGroup() string { - if x, ok := x.GetConsumerTenancy().(*ExportedServicesConsumer_SamenessGroup); ok { - return x.SamenessGroup - } - return "" -} - -type isExportedServicesConsumer_ConsumerTenancy interface { - isExportedServicesConsumer_ConsumerTenancy() -} - -type ExportedServicesConsumer_Peer struct { - Peer string `protobuf:"bytes,1,opt,name=peer,proto3,oneof"` -} - -type ExportedServicesConsumer_Partition struct { - Partition string `protobuf:"bytes,2,opt,name=partition,proto3,oneof"` -} - -type ExportedServicesConsumer_SamenessGroup struct { - SamenessGroup string `protobuf:"bytes,3,opt,name=sameness_group,json=samenessGroup,proto3,oneof"` -} - -func (*ExportedServicesConsumer_Peer) isExportedServicesConsumer_ConsumerTenancy() {} - -func (*ExportedServicesConsumer_Partition) isExportedServicesConsumer_ConsumerTenancy() {} - -func (*ExportedServicesConsumer_SamenessGroup) isExportedServicesConsumer_ConsumerTenancy() {} - -var File_pbmulticluster_v2beta1_exported_services_consumer_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDesc = []byte{ - 0x0a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, - 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, - 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x22, 0x8d, 0x01, 0x0a, 0x18, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x12, 0x14, 0x0a, - 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x04, 0x70, - 0x65, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0d, 0x73, - 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x42, 0x12, 0x0a, 0x10, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x5f, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, - 0x42, 0xd6, 0x02, 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x1d, - 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, - 0x53, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x3b, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, - 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, - 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, - 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, - 0x28, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, -} - -var ( - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescData = file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmulticluster_v2beta1_exported_services_consumer_proto_goTypes = []interface{}{ - (*ExportedServicesConsumer)(nil), // 0: hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer -} -var file_pbmulticluster_v2beta1_exported_services_consumer_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() } -func file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() { - if File_pbmulticluster_v2beta1_exported_services_consumer_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExportedServicesConsumer); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes[0].OneofWrappers = []interface{}{ - (*ExportedServicesConsumer_Peer)(nil), - (*ExportedServicesConsumer_Partition)(nil), - (*ExportedServicesConsumer_SamenessGroup)(nil), - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_exported_services_consumer_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_exported_services_consumer_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_exported_services_consumer_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_exported_services_consumer_proto = out.File - file_pbmulticluster_v2beta1_exported_services_consumer_proto_rawDesc = nil - file_pbmulticluster_v2beta1_exported_services_consumer_proto_goTypes = nil - file_pbmulticluster_v2beta1_exported_services_consumer_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.proto b/proto-public/pbmulticluster/v2beta1/exported_services_consumer.proto deleted file mode 100644 index 1a110099dcf59..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer.proto +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -message ExportedServicesConsumer { - oneof consumer_tenancy { - string peer = 1; - string partition = 2; - string sameness_group = 3; - } -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/exported_services_consumer_deepcopy.gen.go deleted file mode 100644 index 847fe0ec3e31d..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ExportedServicesConsumer within kubernetes types, where deepcopy-gen is used. -func (in *ExportedServicesConsumer) DeepCopyInto(out *ExportedServicesConsumer) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServicesConsumer. Required by controller-gen. -func (in *ExportedServicesConsumer) DeepCopy() *ExportedServicesConsumer { - if in == nil { - return nil - } - out := new(ExportedServicesConsumer) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServicesConsumer. Required by controller-gen. -func (in *ExportedServicesConsumer) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_consumer_json.gen.go b/proto-public/pbmulticluster/v2beta1/exported_services_consumer_json.gen.go deleted file mode 100644 index 3f43f69932a19..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_consumer_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ExportedServicesConsumer -func (this *ExportedServicesConsumer) MarshalJSON() ([]byte, error) { - str, err := ExportedServicesConsumerMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ExportedServicesConsumer -func (this *ExportedServicesConsumer) UnmarshalJSON(b []byte) error { - return ExportedServicesConsumerUnmarshaler.Unmarshal(b, this) -} - -var ( - ExportedServicesConsumerMarshaler = &protojson.MarshalOptions{} - ExportedServicesConsumerUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/exported_services_deepcopy.gen.go deleted file mode 100644 index f5897233ef8b6..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using ExportedServices within kubernetes types, where deepcopy-gen is used. -func (in *ExportedServices) DeepCopyInto(out *ExportedServices) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServices. Required by controller-gen. -func (in *ExportedServices) DeepCopy() *ExportedServices { - if in == nil { - return nil - } - out := new(ExportedServices) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new ExportedServices. Required by controller-gen. -func (in *ExportedServices) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/exported_services_json.gen.go b/proto-public/pbmulticluster/v2beta1/exported_services_json.gen.go deleted file mode 100644 index 40a7cdc38b9b4..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/exported_services_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for ExportedServices -func (this *ExportedServices) MarshalJSON() ([]byte, error) { - str, err := ExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for ExportedServices -func (this *ExportedServices) UnmarshalJSON(b []byte) error { - return ExportedServicesUnmarshaler.Unmarshal(b, this) -} - -var ( - ExportedServicesMarshaler = &protojson.MarshalOptions{} - ExportedServicesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.binary.go b/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.binary.go deleted file mode 100644 index eb000381077b7..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/namespace_exported_services.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *NamespaceExportedServices) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *NamespaceExportedServices) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.go b/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.go deleted file mode 100644 index 5936f86fda119..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.pb.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/namespace_exported_services.proto - -package multiclusterv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type NamespaceExportedServices struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Consumers []*ExportedServicesConsumer `protobuf:"bytes,1,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *NamespaceExportedServices) Reset() { - *x = NamespaceExportedServices{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *NamespaceExportedServices) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*NamespaceExportedServices) ProtoMessage() {} - -func (x *NamespaceExportedServices) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use NamespaceExportedServices.ProtoReflect.Descriptor instead. -func (*NamespaceExportedServices) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescGZIP(), []int{0} -} - -func (x *NamespaceExportedServices) GetConsumers() []*ExportedServicesConsumer { - if x != nil { - return x.Consumers - } - return nil -} - -var File_pbmulticluster_v2beta1_namespace_exported_services_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDesc = []byte{ - 0x0a, 0x38, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x1a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x01, 0x0a, 0x19, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x5d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x42, 0xd7, 0x02, - 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x1e, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, - 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x28, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescData = file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmulticluster_v2beta1_namespace_exported_services_proto_goTypes = []interface{}{ - (*NamespaceExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2beta1.NamespaceExportedServices - (*ExportedServicesConsumer)(nil), // 1: hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer -} -var file_pbmulticluster_v2beta1_namespace_exported_services_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.multicluster.v2beta1.NamespaceExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_namespace_exported_services_proto_init() } -func file_pbmulticluster_v2beta1_namespace_exported_services_proto_init() { - if File_pbmulticluster_v2beta1_namespace_exported_services_proto != nil { - return - } - file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NamespaceExportedServices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_namespace_exported_services_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_namespace_exported_services_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_namespace_exported_services_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_namespace_exported_services_proto = out.File - file_pbmulticluster_v2beta1_namespace_exported_services_proto_rawDesc = nil - file_pbmulticluster_v2beta1_namespace_exported_services_proto_goTypes = nil - file_pbmulticluster_v2beta1_namespace_exported_services_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.proto b/proto-public/pbmulticluster/v2beta1/namespace_exported_services.proto deleted file mode 100644 index 074d44d36063e..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services.proto +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -import "pbmulticluster/v2beta1/exported_services_consumer.proto"; -import "pbresource/annotations.proto"; - -message NamespaceExportedServices { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_NAMESPACE}; - - repeated ExportedServicesConsumer consumers = 1; -} diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/namespace_exported_services_deepcopy.gen.go deleted file mode 100644 index 9d061a755bdae..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using NamespaceExportedServices within kubernetes types, where deepcopy-gen is used. -func (in *NamespaceExportedServices) DeepCopyInto(out *NamespaceExportedServices) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceExportedServices. Required by controller-gen. -func (in *NamespaceExportedServices) DeepCopy() *NamespaceExportedServices { - if in == nil { - return nil - } - out := new(NamespaceExportedServices) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceExportedServices. Required by controller-gen. -func (in *NamespaceExportedServices) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/namespace_exported_services_json.gen.go b/proto-public/pbmulticluster/v2beta1/namespace_exported_services_json.gen.go deleted file mode 100644 index 5d4ee1e42c7a9..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/namespace_exported_services_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for NamespaceExportedServices -func (this *NamespaceExportedServices) MarshalJSON() ([]byte, error) { - str, err := NamespaceExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for NamespaceExportedServices -func (this *NamespaceExportedServices) UnmarshalJSON(b []byte) error { - return NamespaceExportedServicesUnmarshaler.Unmarshal(b, this) -} - -var ( - NamespaceExportedServicesMarshaler = &protojson.MarshalOptions{} - NamespaceExportedServicesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.binary.go b/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.binary.go deleted file mode 100644 index 5518b8a004053..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.binary.go +++ /dev/null @@ -1,18 +0,0 @@ -// Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbmulticluster/v2beta1/partition_exported_services.proto - -package multiclusterv2beta1 - -import ( - "google.golang.org/protobuf/proto" -) - -// MarshalBinary implements encoding.BinaryMarshaler -func (msg *PartitionExportedServices) MarshalBinary() ([]byte, error) { - return proto.Marshal(msg) -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler -func (msg *PartitionExportedServices) UnmarshalBinary(b []byte) error { - return proto.Unmarshal(b, msg) -} diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.go b/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.go deleted file mode 100644 index 116e4784e6fe7..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services.pb.go +++ /dev/null @@ -1,185 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbmulticluster/v2beta1/partition_exported_services.proto - -package multiclusterv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type PartitionExportedServices struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Consumers []*ExportedServicesConsumer `protobuf:"bytes,1,rep,name=consumers,proto3" json:"consumers,omitempty"` -} - -func (x *PartitionExportedServices) Reset() { - *x = PartitionExportedServices{} - if protoimpl.UnsafeEnabled { - mi := &file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PartitionExportedServices) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PartitionExportedServices) ProtoMessage() {} - -func (x *PartitionExportedServices) ProtoReflect() protoreflect.Message { - mi := &file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PartitionExportedServices.ProtoReflect.Descriptor instead. -func (*PartitionExportedServices) Descriptor() ([]byte, []int) { - return file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescGZIP(), []int{0} -} - -func (x *PartitionExportedServices) GetConsumers() []*ExportedServicesConsumer { - if x != nil { - return x.Consumers - } - return nil -} - -var File_pbmulticluster_v2beta1_partition_exported_services_proto protoreflect.FileDescriptor - -var file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDesc = []byte{ - 0x0a, 0x38, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x25, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x1a, 0x37, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, - 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, - 0x65, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x01, 0x0a, 0x19, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x5d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, - 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6d, 0x65, 0x72, 0x73, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x42, 0xd7, 0x02, - 0x0a, 0x29, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x1e, 0x50, 0x61, 0x72, - 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x53, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, - 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x6d, - 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x76, 0x32, 0x62, 0x65, 0x74, - 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x4d, 0xaa, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xca, 0x02, 0x25, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x31, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x75, 0x6c, 0x74, - 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x28, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, - 0x3a, 0x3a, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x3a, 0x3a, - 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescOnce sync.Once - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescData = file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDesc -) - -func file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescGZIP() []byte { - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescOnce.Do(func() { - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescData) - }) - return file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDescData -} - -var file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbmulticluster_v2beta1_partition_exported_services_proto_goTypes = []interface{}{ - (*PartitionExportedServices)(nil), // 0: hashicorp.consul.multicluster.v2beta1.PartitionExportedServices - (*ExportedServicesConsumer)(nil), // 1: hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer -} -var file_pbmulticluster_v2beta1_partition_exported_services_proto_depIdxs = []int32{ - 1, // 0: hashicorp.consul.multicluster.v2beta1.PartitionExportedServices.consumers:type_name -> hashicorp.consul.multicluster.v2beta1.ExportedServicesConsumer - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_pbmulticluster_v2beta1_partition_exported_services_proto_init() } -func file_pbmulticluster_v2beta1_partition_exported_services_proto_init() { - if File_pbmulticluster_v2beta1_partition_exported_services_proto != nil { - return - } - file_pbmulticluster_v2beta1_exported_services_consumer_proto_init() - if !protoimpl.UnsafeEnabled { - file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PartitionExportedServices); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbmulticluster_v2beta1_partition_exported_services_proto_goTypes, - DependencyIndexes: file_pbmulticluster_v2beta1_partition_exported_services_proto_depIdxs, - MessageInfos: file_pbmulticluster_v2beta1_partition_exported_services_proto_msgTypes, - }.Build() - File_pbmulticluster_v2beta1_partition_exported_services_proto = out.File - file_pbmulticluster_v2beta1_partition_exported_services_proto_rawDesc = nil - file_pbmulticluster_v2beta1_partition_exported_services_proto_goTypes = nil - file_pbmulticluster_v2beta1_partition_exported_services_proto_depIdxs = nil -} diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services.proto b/proto-public/pbmulticluster/v2beta1/partition_exported_services.proto deleted file mode 100644 index b3cf249a0c90f..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services.proto +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -syntax = "proto3"; - -package hashicorp.consul.multicluster.v2beta1; - -import "pbmulticluster/v2beta1/exported_services_consumer.proto"; -import "pbresource/annotations.proto"; - -message PartitionExportedServices { - option (hashicorp.consul.resource.spec) = {scope: SCOPE_PARTITION}; - - repeated ExportedServicesConsumer consumers = 1; -} diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services_deepcopy.gen.go b/proto-public/pbmulticluster/v2beta1/partition_exported_services_deepcopy.gen.go deleted file mode 100644 index 9f048e16d2008..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services_deepcopy.gen.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - proto "google.golang.org/protobuf/proto" -) - -// DeepCopyInto supports using PartitionExportedServices within kubernetes types, where deepcopy-gen is used. -func (in *PartitionExportedServices) DeepCopyInto(out *PartitionExportedServices) { - proto.Reset(out) - proto.Merge(out, proto.Clone(in)) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartitionExportedServices. Required by controller-gen. -func (in *PartitionExportedServices) DeepCopy() *PartitionExportedServices { - if in == nil { - return nil - } - out := new(PartitionExportedServices) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new PartitionExportedServices. Required by controller-gen. -func (in *PartitionExportedServices) DeepCopyInterface() interface{} { - return in.DeepCopy() -} diff --git a/proto-public/pbmulticluster/v2beta1/partition_exported_services_json.gen.go b/proto-public/pbmulticluster/v2beta1/partition_exported_services_json.gen.go deleted file mode 100644 index e9dfafd702740..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/partition_exported_services_json.gen.go +++ /dev/null @@ -1,22 +0,0 @@ -// Code generated by protoc-json-shim. DO NOT EDIT. -package multiclusterv2beta1 - -import ( - protojson "google.golang.org/protobuf/encoding/protojson" -) - -// MarshalJSON is a custom marshaler for PartitionExportedServices -func (this *PartitionExportedServices) MarshalJSON() ([]byte, error) { - str, err := PartitionExportedServicesMarshaler.Marshal(this) - return []byte(str), err -} - -// UnmarshalJSON is a custom unmarshaler for PartitionExportedServices -func (this *PartitionExportedServices) UnmarshalJSON(b []byte) error { - return PartitionExportedServicesUnmarshaler.Unmarshal(b, this) -} - -var ( - PartitionExportedServicesMarshaler = &protojson.MarshalOptions{} - PartitionExportedServicesUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false} -) diff --git a/proto-public/pbmulticluster/v2beta1/resource_types.gen.go b/proto-public/pbmulticluster/v2beta1/resource_types.gen.go deleted file mode 100644 index 910811b98f931..0000000000000 --- a/proto-public/pbmulticluster/v2beta1/resource_types.gen.go +++ /dev/null @@ -1,43 +0,0 @@ -// Code generated by protoc-gen-resource-types. DO NOT EDIT. - -package multiclusterv2beta1 - -import ( - "github.com/hashicorp/consul/proto-public/pbresource" -) - -const ( - GroupName = "multicluster" - Version = "v2beta1" - - ComputedExportedServicesKind = "ComputedExportedServices" - ExportedServicesKind = "ExportedServices" - NamespaceExportedServicesKind = "NamespaceExportedServices" - PartitionExportedServicesKind = "PartitionExportedServices" -) - -var ( - ComputedExportedServicesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ComputedExportedServicesKind, - } - - ExportedServicesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: ExportedServicesKind, - } - - NamespaceExportedServicesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: NamespaceExportedServicesKind, - } - - PartitionExportedServicesType = &pbresource.Type{ - Group: GroupName, - GroupVersion: Version, - Kind: PartitionExportedServicesKind, - } -) diff --git a/proto-public/pbtenancy/v2beta1/namespace.pb.binary.go b/proto-public/pbtenancy/v1alpha1/namespace.pb.binary.go similarity index 84% rename from proto-public/pbtenancy/v2beta1/namespace.pb.binary.go rename to proto-public/pbtenancy/v1alpha1/namespace.pb.binary.go index 1884a0943b0da..f6097062d32dc 100644 --- a/proto-public/pbtenancy/v2beta1/namespace.pb.binary.go +++ b/proto-public/pbtenancy/v1alpha1/namespace.pb.binary.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-binary. DO NOT EDIT. -// source: pbtenancy/v2beta1/namespace.proto +// source: pbtenancy/v1alpha1/namespace.proto -package tenancyv2beta1 +package tenancyv1alpha1 import ( "google.golang.org/protobuf/proto" diff --git a/proto-public/pbtenancy/v1alpha1/namespace.pb.go b/proto-public/pbtenancy/v1alpha1/namespace.pb.go new file mode 100644 index 0000000000000..e7fec0b5d0086 --- /dev/null +++ b/proto-public/pbtenancy/v1alpha1/namespace.pb.go @@ -0,0 +1,172 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.30.0 +// protoc (unknown) +// source: pbtenancy/v1alpha1/namespace.proto + +package tenancyv1alpha1 + +import ( + _ "github.com/hashicorp/consul/proto-public/pbresource" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// The name of the Namespace is in the outer Resource.ID.Name. +// It must be unique within a partition and must be a +// DNS hostname. There are also other reserved names that may not be used. +type Namespace struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Description is where the user puts any information they want + // about the namespace. It is not used internally. + Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` +} + +func (x *Namespace) Reset() { + *x = Namespace{} + if protoimpl.UnsafeEnabled { + mi := &file_pbtenancy_v1alpha1_namespace_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Namespace) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Namespace) ProtoMessage() {} + +func (x *Namespace) ProtoReflect() protoreflect.Message { + mi := &file_pbtenancy_v1alpha1_namespace_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Namespace.ProtoReflect.Descriptor instead. +func (*Namespace) Descriptor() ([]byte, []int) { + return file_pbtenancy_v1alpha1_namespace_proto_rawDescGZIP(), []int{0} +} + +func (x *Namespace) GetDescription() string { + if x != nil { + return x.Description + } + return "" +} + +var File_pbtenancy_v1alpha1_namespace_proto protoreflect.FileDescriptor + +var file_pbtenancy_v1alpha1_namespace_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x70, 0x62, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2f, 0x76, 0x31, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, + 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x76, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x42, 0xab, 0x02, 0x0a, + 0x25, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x76, 0x31, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x42, 0x0e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x4b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, + 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x2f, 0x70, 0x62, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2f, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0x3b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x76, 0x31, 0x61, + 0x6c, 0x70, 0x68, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x54, 0xaa, 0x02, 0x21, 0x48, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x54, + 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0xca, + 0x02, 0x21, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, + 0x75, 0x6c, 0x5c, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x5c, 0x56, 0x31, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x31, 0xe2, 0x02, 0x2d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x5c, 0x56, + 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x24, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, + 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, + 0x3a, 0x3a, 0x56, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_pbtenancy_v1alpha1_namespace_proto_rawDescOnce sync.Once + file_pbtenancy_v1alpha1_namespace_proto_rawDescData = file_pbtenancy_v1alpha1_namespace_proto_rawDesc +) + +func file_pbtenancy_v1alpha1_namespace_proto_rawDescGZIP() []byte { + file_pbtenancy_v1alpha1_namespace_proto_rawDescOnce.Do(func() { + file_pbtenancy_v1alpha1_namespace_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbtenancy_v1alpha1_namespace_proto_rawDescData) + }) + return file_pbtenancy_v1alpha1_namespace_proto_rawDescData +} + +var file_pbtenancy_v1alpha1_namespace_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_pbtenancy_v1alpha1_namespace_proto_goTypes = []interface{}{ + (*Namespace)(nil), // 0: hashicorp.consul.tenancy.v1alpha1.Namespace +} +var file_pbtenancy_v1alpha1_namespace_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_pbtenancy_v1alpha1_namespace_proto_init() } +func file_pbtenancy_v1alpha1_namespace_proto_init() { + if File_pbtenancy_v1alpha1_namespace_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_pbtenancy_v1alpha1_namespace_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Namespace); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbtenancy_v1alpha1_namespace_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbtenancy_v1alpha1_namespace_proto_goTypes, + DependencyIndexes: file_pbtenancy_v1alpha1_namespace_proto_depIdxs, + MessageInfos: file_pbtenancy_v1alpha1_namespace_proto_msgTypes, + }.Build() + File_pbtenancy_v1alpha1_namespace_proto = out.File + file_pbtenancy_v1alpha1_namespace_proto_rawDesc = nil + file_pbtenancy_v1alpha1_namespace_proto_goTypes = nil + file_pbtenancy_v1alpha1_namespace_proto_depIdxs = nil +} diff --git a/proto-public/pbtenancy/v2beta1/namespace.proto b/proto-public/pbtenancy/v1alpha1/namespace.proto similarity index 91% rename from proto-public/pbtenancy/v2beta1/namespace.proto rename to proto-public/pbtenancy/v1alpha1/namespace.proto index 6d4a739f6e21f..e90b10c1e573c 100644 --- a/proto-public/pbtenancy/v2beta1/namespace.proto +++ b/proto-public/pbtenancy/v1alpha1/namespace.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -package hashicorp.consul.tenancy.v2beta1; +package hashicorp.consul.tenancy.v1alpha1; import "pbresource/annotations.proto"; diff --git a/proto-public/pbtenancy/v2beta1/namespace_deepcopy.gen.go b/proto-public/pbtenancy/v1alpha1/namespace_deepcopy.gen.go similarity index 97% rename from proto-public/pbtenancy/v2beta1/namespace_deepcopy.gen.go rename to proto-public/pbtenancy/v1alpha1/namespace_deepcopy.gen.go index 2384004c869f3..97af531ab3330 100644 --- a/proto-public/pbtenancy/v2beta1/namespace_deepcopy.gen.go +++ b/proto-public/pbtenancy/v1alpha1/namespace_deepcopy.gen.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-deepcopy. DO NOT EDIT. -package tenancyv2beta1 +package tenancyv1alpha1 import ( proto "google.golang.org/protobuf/proto" diff --git a/proto-public/pbtenancy/v2beta1/namespace_json.gen.go b/proto-public/pbtenancy/v1alpha1/namespace_json.gen.go similarity index 96% rename from proto-public/pbtenancy/v2beta1/namespace_json.gen.go rename to proto-public/pbtenancy/v1alpha1/namespace_json.gen.go index 4ad7901c16c3c..9df4de9df7199 100644 --- a/proto-public/pbtenancy/v2beta1/namespace_json.gen.go +++ b/proto-public/pbtenancy/v1alpha1/namespace_json.gen.go @@ -1,5 +1,5 @@ // Code generated by protoc-json-shim. DO NOT EDIT. -package tenancyv2beta1 +package tenancyv1alpha1 import ( protojson "google.golang.org/protobuf/encoding/protojson" diff --git a/proto-public/pbtenancy/v2beta1/resource_types.gen.go b/proto-public/pbtenancy/v1alpha1/resource_types.gen.go similarity index 87% rename from proto-public/pbtenancy/v2beta1/resource_types.gen.go rename to proto-public/pbtenancy/v1alpha1/resource_types.gen.go index b0c3040408234..f1b6f70cf1038 100644 --- a/proto-public/pbtenancy/v2beta1/resource_types.gen.go +++ b/proto-public/pbtenancy/v1alpha1/resource_types.gen.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-resource-types. DO NOT EDIT. -package tenancyv2beta1 +package tenancyv1alpha1 import ( "github.com/hashicorp/consul/proto-public/pbresource" @@ -8,7 +8,7 @@ import ( const ( GroupName = "tenancy" - Version = "v2beta1" + Version = "v1alpha1" NamespaceKind = "Namespace" ) diff --git a/proto-public/pbtenancy/v2beta1/namespace.pb.go b/proto-public/pbtenancy/v2beta1/namespace.pb.go deleted file mode 100644 index 2118814a68a7f..0000000000000 --- a/proto-public/pbtenancy/v2beta1/namespace.pb.go +++ /dev/null @@ -1,171 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.30.0 -// protoc (unknown) -// source: pbtenancy/v2beta1/namespace.proto - -package tenancyv2beta1 - -import ( - _ "github.com/hashicorp/consul/proto-public/pbresource" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// The name of the Namespace is in the outer Resource.ID.Name. -// It must be unique within a partition and must be a -// DNS hostname. There are also other reserved names that may not be used. -type Namespace struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Description is where the user puts any information they want - // about the namespace. It is not used internally. - Description string `protobuf:"bytes,1,opt,name=description,proto3" json:"description,omitempty"` -} - -func (x *Namespace) Reset() { - *x = Namespace{} - if protoimpl.UnsafeEnabled { - mi := &file_pbtenancy_v2beta1_namespace_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Namespace) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Namespace) ProtoMessage() {} - -func (x *Namespace) ProtoReflect() protoreflect.Message { - mi := &file_pbtenancy_v2beta1_namespace_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Namespace.ProtoReflect.Descriptor instead. -func (*Namespace) Descriptor() ([]byte, []int) { - return file_pbtenancy_v2beta1_namespace_proto_rawDescGZIP(), []int{0} -} - -func (x *Namespace) GetDescription() string { - if x != nil { - return x.Description - } - return "" -} - -var File_pbtenancy_v2beta1_namespace_proto protoreflect.FileDescriptor - -var file_pbtenancy_v2beta1_namespace_proto_rawDesc = []byte{ - 0x0a, 0x21, 0x70, 0x62, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2f, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x20, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x76, 0x32, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x1a, 0x1c, 0x70, 0x62, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x42, 0xa4, 0x02, 0x0a, 0x24, 0x63, - 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, - 0x73, 0x75, 0x6c, 0x2e, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2e, 0x76, 0x32, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x42, 0x0e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x49, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, - 0x70, 0x62, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x3b, 0x74, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, - 0xa2, 0x02, 0x03, 0x48, 0x43, 0x54, 0xaa, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, - 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, - 0x79, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x54, 0x65, 0x6e, - 0x61, 0x6e, 0x63, 0x79, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x2c, 0x48, - 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, - 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x23, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, - 0x3a, 0x54, 0x65, 0x6e, 0x61, 0x6e, 0x63, 0x79, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_pbtenancy_v2beta1_namespace_proto_rawDescOnce sync.Once - file_pbtenancy_v2beta1_namespace_proto_rawDescData = file_pbtenancy_v2beta1_namespace_proto_rawDesc -) - -func file_pbtenancy_v2beta1_namespace_proto_rawDescGZIP() []byte { - file_pbtenancy_v2beta1_namespace_proto_rawDescOnce.Do(func() { - file_pbtenancy_v2beta1_namespace_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbtenancy_v2beta1_namespace_proto_rawDescData) - }) - return file_pbtenancy_v2beta1_namespace_proto_rawDescData -} - -var file_pbtenancy_v2beta1_namespace_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_pbtenancy_v2beta1_namespace_proto_goTypes = []interface{}{ - (*Namespace)(nil), // 0: hashicorp.consul.tenancy.v2beta1.Namespace -} -var file_pbtenancy_v2beta1_namespace_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_pbtenancy_v2beta1_namespace_proto_init() } -func file_pbtenancy_v2beta1_namespace_proto_init() { - if File_pbtenancy_v2beta1_namespace_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_pbtenancy_v2beta1_namespace_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Namespace); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_pbtenancy_v2beta1_namespace_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_pbtenancy_v2beta1_namespace_proto_goTypes, - DependencyIndexes: file_pbtenancy_v2beta1_namespace_proto_depIdxs, - MessageInfos: file_pbtenancy_v2beta1_namespace_proto_msgTypes, - }.Build() - File_pbtenancy_v2beta1_namespace_proto = out.File - file_pbtenancy_v2beta1_namespace_proto_rawDesc = nil - file_pbtenancy_v2beta1_namespace_proto_goTypes = nil - file_pbtenancy_v2beta1_namespace_proto_depIdxs = nil -} diff --git a/test-integ/connect/snapshot_test.go b/test-integ/connect/snapshot_test.go index 469562a160748..643e64d4b6f9e 100644 --- a/test-integ/connect/snapshot_test.go +++ b/test-integ/connect/snapshot_test.go @@ -204,7 +204,7 @@ func Test_Snapshot_Restore_Agentless(t *testing.T) { // Add a new static-server cfg = sp.Config() cluster = cfg.Cluster("dc1") - cluster.Nodes[3].Disabled = false // client 3 -- static-server + cluster.Nodes[3].Disabled = false // client 3 -- new static-server require.NoError(t, sp.Relaunch(cfg)) // Ensure the static-client connected to static-server diff --git a/test-integ/go.mod b/test-integ/go.mod index 44dc740f756bd..73b8dc62d80a8 100644 --- a/test-integ/go.mod +++ b/test-integ/go.mod @@ -15,6 +15,9 @@ require ( ) require ( + cloud.google.com/go/compute v1.20.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v1.1.1 // indirect dario.cat/mergo v1.0.0 // indirect fortio.org/dflag v1.5.2 // indirect fortio.org/fortio v1.54.0 // indirect @@ -22,89 +25,218 @@ require ( fortio.org/sets v1.0.2 // indirect fortio.org/version v1.0.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/DataDog/datadog-go v4.8.2+incompatible // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/agext/levenshtein v1.2.3 // indirect + github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e // indirect github.com/armon/go-metrics v0.4.1 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/avast/retry-go v3.0.0+incompatible // indirect + github.com/aws/aws-sdk-go v1.44.289 // indirect + github.com/benbjohnson/immutable v0.4.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/boltdb/bolt v1.3.1 // indirect + github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible // indirect + github.com/circonus-labs/circonusllhist v0.1.3 // indirect + github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/containerd/containerd v1.7.3 // indirect + github.com/coreos/etcd v3.3.27+incompatible // indirect + github.com/coreos/go-oidc v2.1.0+incompatible // indirect + github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect + github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.5+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/emicklei/go-restful/v3 v3.10.1 // indirect + github.com/envoyproxy/go-control-plane v0.11.1 // indirect + github.com/envoyproxy/protoc-gen-validate v1.0.1 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fatih/color v1.14.1 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/go-jose/go-jose/v3 v3.0.0 // indirect - github.com/go-test/deep v1.1.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/analysis v0.21.4 // indirect + github.com/go-openapi/errors v0.20.3 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/loads v0.21.2 // indirect + github.com/go-openapi/runtime v0.25.0 // indirect + github.com/go-openapi/spec v0.20.8 // indirect + github.com/go-openapi/strfmt v0.21.3 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/validate v0.22.1 // indirect + github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.0.1 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/s2a-go v0.1.4 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.11.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect github.com/hashicorp/consul v1.16.1 // indirect + github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 // indirect + github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 // indirect github.com/hashicorp/consul-server-connection-manager v0.1.4 // indirect + github.com/hashicorp/consul/envoyextensions v0.5.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-bexpr v0.1.2 // indirect + github.com/hashicorp/go-connlimit v0.3.0 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-memdb v1.3.4 // indirect github.com/hashicorp/go-msgpack v1.1.5 // indirect + github.com/hashicorp/go-msgpack/v2 v2.0.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-netaddrs v0.1.0 // indirect + github.com/hashicorp/go-plugin v1.4.5 // indirect + github.com/hashicorp/go-raftchunking v0.7.0 // indirect + github.com/hashicorp/go-retryablehttp v0.6.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/go-syslog v1.0.0 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.2.1 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl/v2 v2.16.2 // indirect + github.com/hashicorp/hcp-scada-provider v0.2.3 // indirect + github.com/hashicorp/hcp-sdk-go v0.61.0 // indirect + github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect + github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 // indirect + github.com/hashicorp/raft v1.5.0 // indirect + github.com/hashicorp/raft-autopilot v0.1.6 // indirect + github.com/hashicorp/raft-boltdb/v2 v2.2.2 // indirect + github.com/hashicorp/raft-wal v0.4.1 // indirect github.com/hashicorp/serf v0.10.1 // indirect + github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 // indirect + github.com/hashicorp/vault/api v1.8.3 // indirect + github.com/hashicorp/vault/api/auth/gcp v0.3.0 // indirect + github.com/hashicorp/vault/sdk v0.7.0 // indirect + github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect + github.com/imdario/mergo v0.3.15 // indirect github.com/itchyny/timefmt-go v0.1.5 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/magiconair/properties v1.8.7 // 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/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect + github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/pointerstructure v1.2.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/patternmatcher v0.5.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect + github.com/oklog/ulid/v2 v2.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/opencontainers/runc v1.1.8 // indirect + github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect github.com/otiai10/copy v1.10.0 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/rboyer/safeio v0.2.3 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/segmentio/fasthash v1.0.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect + github.com/stretchr/objx v0.5.0 // indirect github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 // indirect github.com/testcontainers/testcontainers-go v0.22.0 // indirect + github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect + github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/zclconf/go-cty v1.12.1 // indirect + go.etcd.io/bbolt v1.3.7 // indirect + go.mongodb.org/mongo-driver v1.11.0 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect + go.opentelemetry.io/proto/otlp v0.19.0 // indirect + go.uber.org/atomic v1.9.0 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.17.0 // indirect + golang.org/x/oauth2 v0.8.0 // indirect + golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect + golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + google.golang.org/api v0.126.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect google.golang.org/grpc v1.57.2 // indirect google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/square/go-jose.v2 v2.5.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.26.2 // indirect + k8s.io/apimachinery v0.26.2 // indirect + k8s.io/client-go v0.26.2 // indirect + k8s.io/klog/v2 v2.90.1 // indirect + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( diff --git a/test-integ/go.sum b/test-integ/go.sum index d5338549f7d78..09543e235cc2c 100644 --- a/test-integ/go.sum +++ b/test-integ/go.sum @@ -1,5 +1,56 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= fortio.org/assert v1.1.4 h1:Za1RaG+OjsTMpQS3J3UCvTF6wc4+IOHCz+jAOU37Y4o= fortio.org/dflag v1.5.2 h1:F9XVRj4Qr2IbJP7BMj7XZc9wB0Q/RZ61Ool+4YPVad8= fortio.org/dflag v1.5.2/go.mod h1:ppb/A8u+KKg+qUUYZNYuvRnXuVb8IsdHb/XGzsmjkN8= @@ -14,42 +65,98 @@ fortio.org/version v1.0.2/go.mod h1:2JQp9Ax+tm6QKiGuzR5nJY63kFeANcgrZ0osoQFDVm0= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v4.8.2+incompatible h1:qbcKSx29aBLD+5QLvlQZlGmRMF/FfGqFLFev/1TDzRo= +github.com/DataDog/datadog-go v4.8.2+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 h1:K4N91T1+RlSlx+t2dujeDviy4ehSGVjEltluDgmeHS4= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.156/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= +github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.44.289 h1:5CVEjiHFvdiVlKPBzv0rjG4zH/21W/onT18R5AH/qx0= +github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/benbjohnson/immutable v0.4.0 h1:CTqXbEerYso8YzVPxmWxh2gnoRQbbB9X1quUC8+vGZA= +github.com/benbjohnson/immutable v0.4.0/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +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.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= +github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible h1:C29Ae4G5GtYyYMm1aztcyj/J5ckgJm2zwdDajFbx1NY= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+gqO04wryn5h75LSazbRlnya1k= +github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= +github.com/coreos/etcd v3.3.27+incompatible h1:QIudLb9KeBsE5zyYxd1mjzRSkzLg9Wf9QlRwFgd6oTA= +github.com/coreos/etcd v3.3.27+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf h1:GOPo6vn/vTN+3IwZBvXX0y5doJfSC7My0cdzelyOCsQ= +github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -64,112 +171,412 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= +github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= +github.com/envoyproxy/go-control-plane v0.11.1/go.mod h1:uhMcXKCQMEJHiAb0w+YGefQLaTEw+YhGluxZkrTmD0g= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ= +github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= +github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= +github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= +github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= +github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= +github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= +github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= +github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= +github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= +github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= +github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE= +github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2 h1:AtvtonGEH/fZK0XPNNBdB6swgy7Iudfx88wzyIpwqJ8= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= +github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 h1:1ZEjnveDe20yFa6lSkfdQZm5BR/b271n0MsB5R2L3us= +github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706/go.mod h1:1Cs8FlmD1BfSQXJGcFLSV5FuIx1AbJP+EJGdxosoS2g= +github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 h1:wzWurXrxfSyG1PHskIZlfuXlTSCj1Tsyatp9DtaasuY= +github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69/go.mod h1:svUZZDvotY8zTODknUePc6mZ9pX8nN0ViGwWcUSOBEA= github.com/hashicorp/consul-server-connection-manager v0.1.4 h1:wrcSRV6WGXFBNpNbN6XsdoGgBOyso7ZbN5VaWPEX1jY= github.com/hashicorp/consul-server-connection-manager v0.1.4/go.mod h1:LMqHkALoLP0HUQKOG21xXYr0YPUayIQIHNTlmxG100E= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.2 h1:ijMXI4qERbzxbCnkxmfUtwMyjrrk3y+Vt0MxojNCbBs= +github.com/hashicorp/go-bexpr v0.1.2/go.mod h1:ANbpTX1oAql27TZkKVeW8p1w8NTdnyzPe/0qqPCKohU= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-connlimit v0.3.0 h1:oAojHGjFxUTTTA8c5XXnDqWJ2HLuWbDiBPTpWvNzvqM= +github.com/hashicorp/go-connlimit v0.3.0/go.mod h1:OUj9FGL1tPIhl/2RCfzYHrIiWj+VVPGNyVPnUX8AqS0= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0/go.mod h1:xvb32K2keAc+R8DSFG2IwDcydK9DBQE+fGA5fsw6hSk= +github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= +github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4= +github.com/hashicorp/go-msgpack/v2 v2.0.0 h1:c1fiLq1LNghmLOry1ipGhvLDi+/zEoaEP2JrE1oFJ9s= +github.com/hashicorp/go-msgpack/v2 v2.0.0/go.mod h1:JIxYkkFJRDDRSoWQBSh7s9QAVThq+82iWmUpmE4jKak= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-netaddrs v0.1.0 h1:TnlYvODD4C/wO+j7cX1z69kV5gOzI87u3OcUinANaW8= github.com/hashicorp/go-netaddrs v0.1.0/go.mod h1:33+a/emi5R5dqRspOuZKO0E+Tuz5WV1F84eRWALkedA= +github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= +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-raftchunking v0.7.0 h1:APNMnCXmTOhumkFv/GpJIbq7HteWF7EnGZ3875lRN0Y= +github.com/hashicorp/go-raftchunking v0.7.0/go.mod h1:Dg/eBOaJzE0jYKNwNLs5IA5j0OSmL5HoCUiMy3mDmrI= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-retryablehttp v0.6.7 h1:8/CAEZt/+F7kR7GevNHulKkUjLht3CPmn7egmhieNKo= +github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= +github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= +github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= +github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= +github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwMrUAE= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.16.2 h1:mpkHZh/Tv+xet3sy3F9Ld4FyI2tUpWe9x3XtPx9f1a0= github.com/hashicorp/hcl/v2 v2.16.2/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6KocSLCMCXng= +github.com/hashicorp/hcp-scada-provider v0.2.3 h1:AarYR+/Pcv+cMvPdAlb92uOBmZfEH6ny4+DT+4NY2VQ= +github.com/hashicorp/hcp-scada-provider v0.2.3/go.mod h1:ZFTgGwkzNv99PLQjTsulzaCplCzOTBh0IUQsPKzrQFo= +github.com/hashicorp/hcp-sdk-go v0.61.0 h1:x4hJ8SlLI5WCE8Uzcu4q5jfdOEz/hFxfUkhAdoFdzSg= +github.com/hashicorp/hcp-sdk-go v0.61.0/go.mod h1:xP7wmWAmdMxs/7+ovH3jZn+MCDhHRj50Rn+m7JIY3Ck= +github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 h1:n9J0rwVWXDpNd5iZnwY7w4WZyq53/rROeI7OVvLW8Ok= +github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 h1:kBpVVl1sl3MaSrs97e0+pDQhSrqJv9gVbSUrPpVfl1w= +github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0/go.mod h1:6pdNz0vo0mF0GvhwDG56O3N18qBrAz/XRIcfINfTbwo= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft v1.3.11/go.mod h1:J8naEwc6XaaCfts7+28whSeRvCqTd6e20BlCU3LtEO4= +github.com/hashicorp/raft v1.5.0 h1:uNs9EfJ4FwiArZRxxfd/dQ5d33nV31/CdCHArH89hT8= +github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M= +github.com/hashicorp/raft-autopilot v0.1.6 h1:C1q3RNF2FfXNZfHWbvVAu0QixaQK8K5pX4O5lh+9z4I= +github.com/hashicorp/raft-autopilot v0.1.6/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw= +github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= +github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qRd6nFJYYS6Iqnc/8HcUmko2/2Gw8qTFEmxDLii6W5I= +github.com/hashicorp/raft-boltdb v0.0.0-20220329195025-15018e9b97e0 h1:CO8dBMLH6dvE1jTn/30ZZw3iuPsNfajshWoJTnVc5cc= +github.com/hashicorp/raft-boltdb/v2 v2.2.2 h1:rlkPtOllgIcKLxVT4nutqlTH2NRFn+tO1wwZk/4Dxqw= +github.com/hashicorp/raft-boltdb/v2 v2.2.2/go.mod h1:N8YgaZgNJLpZC+h+by7vDu5rzsRgONThTEeUS3zWbfY= +github.com/hashicorp/raft-wal v0.4.1 h1:aU8XZ6x8R9BAIB/83Z1dTDtXvDVmv9YVYeXxd/1QBSA= +github.com/hashicorp/raft-wal v0.4.1/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 h1:O6tNk0s/arubLUbLeCyaRs5xGo9VwmbQazISY/BfPK4= +github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0/go.mod h1:We3fJplmALwK1VpjwrLuXr/4QCQHYMdnXLHmLUU6Ntg= +github.com/hashicorp/vault/api v1.8.0/go.mod h1:uJrw6D3y9Rv7hhmS17JQC50jbPDAZdjZoTtrCCxxs7E= +github.com/hashicorp/vault/api v1.8.3 h1:cHQOLcMhBR+aVI0HzhPxO62w2+gJhIrKguQNONPzu6o= +github.com/hashicorp/vault/api v1.8.3/go.mod h1:4g/9lj9lmuJQMtT6CmVMHC5FW1yENaVv+Nv4ZfG8fAg= +github.com/hashicorp/vault/api/auth/gcp v0.3.0 h1:taum+3pCmOXnNgEKHlQbmgXmKw5daWHk7YJrLPP/w8g= +github.com/hashicorp/vault/api/auth/gcp v0.3.0/go.mod h1:gnNBFOASYUaFunedTHOzdir7vKcHL3skWBUzEn263bo= +github.com/hashicorp/vault/sdk v0.6.0/go.mod h1:+DRpzoXIdMvKc88R4qxr+edwy/RvH5QK8itmxLiDHLc= +github.com/hashicorp/vault/sdk v0.7.0 h1:2pQRO40R1etpKkia5fb4kjrdYMx3BHklPxl1pxpxDHg= +github.com/hashicorp/vault/sdk v0.7.0/go.mod h1:KyfArJkhooyba7gYCKSq8v66QdqJmnbAxtV/OX1+JTs= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= +github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/itchyny/gojq v0.12.13 h1:IxyYlHYIlspQHHTE0f3cJF0NKDMfajxViuhBLnHd/QU= github.com/itchyny/gojq v0.12.13/go.mod h1:JzwzAqenfhrPUuwbmEz3nu3JQmFLlQTQMUcOdnu/Sf4= github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -179,6 +586,7 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -194,16 +602,33 @@ github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= +github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU= +github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= +github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= +github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= @@ -213,24 +638,49 @@ github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWK github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= +github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= +github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.8 h1:zICRlc+C1XzivLc3nzE+cbJV4LIi8tib6YG0MqC6OqA= github.com/opencontainers/runc v1.1.8/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= +github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU= github.com/otiai10/copy v1.10.0 h1:znyI7l134wNg/wDktoVQPxPkgvhDfGCYUasey+h0rDQ= github.com/otiai10/copy v1.10.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -240,161 +690,658 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rboyer/safeio v0.2.3 h1:gUybicx1kp8nuM4vO0GA5xTBX58/OBd8MQuErBfDxP8= github.com/rboyer/safeio v0.2.3/go.mod h1:d7RMmt7utQBJZ4B7f0H/cU/EdZibQAU1Y8NWepK2dS8= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= +github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLqFypcxvLmlvEciCHL7+Lv+4vwZqecI= github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI= github.com/testcontainers/testcontainers-go v0.22.0 h1:hOK4NzNu82VZcKEB1aP9LO1xYssVFMvlfeuDW9JMmV0= github.com/testcontainers/testcontainers-go v0.22.0/go.mod h1:k0YiPa26xJCRUbUkYqy5rY6NGvSbVCeUBXCvucscBR4= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= +github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY= github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= +go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= +go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= +go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= +google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e h1:xIXmWJ303kJCuogpj0bHq+dcjcZHU+XFyc1I0Yl9cRg= +google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= +google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU= +google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.57.2 h1:uw37EN34aMFFXB2QPW7Tq6tdTbind1GpRxw5aOX3a5k= google.golang.org/grpc v1.57.2/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= +k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= +k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= +k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= +k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index 18af2c9954bd5..8161503c518ef 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -34,6 +34,9 @@ require ( ) require ( + cloud.google.com/go/compute v1.20.1 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect + cloud.google.com/go/iam v1.1.1 // indirect dario.cat/mergo v1.0.0 // indirect fortio.org/dflag v1.5.2 // indirect fortio.org/log v1.3.0 // indirect @@ -42,10 +45,16 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/DataDog/datadog-go v4.8.2+incompatible // indirect github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 // indirect + github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/armon/go-radix v1.0.0 // indirect + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/aws/aws-sdk-go v1.44.289 // indirect + github.com/benbjohnson/immutable v0.4.0 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/boltdb/bolt v1.3.1 // indirect + github.com/cenkalti/backoff/v3 v3.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect @@ -53,79 +62,174 @@ require ( github.com/circonus-labs/circonusllhist v0.1.3 // indirect github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/containerd/containerd v1.7.3 // indirect + github.com/coreos/etcd v3.3.27+incompatible // indirect + github.com/coreos/go-oidc v2.1.0+incompatible // indirect + github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect + github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/deckarep/golang-set/v2 v2.3.1 // indirect github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect + github.com/emicklei/go-restful/v3 v3.10.1 // indirect github.com/envoyproxy/go-control-plane v0.11.1 // indirect github.com/envoyproxy/protoc-gen-validate v1.0.1 // indirect github.com/fatih/color v1.14.1 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-openapi/analysis v0.21.4 // indirect + github.com/go-openapi/errors v0.20.3 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/jsonreference v0.20.0 // indirect + github.com/go-openapi/loads v0.21.2 // indirect + github.com/go-openapi/runtime v0.25.0 // indirect + github.com/go-openapi/spec v0.20.8 // indirect + github.com/go-openapi/strfmt v0.21.3 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/go-openapi/validate v0.22.1 // indirect + github.com/go-ozzo/ozzo-validation v3.6.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.0.1 // indirect + github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/s2a-go v0.1.4 // indirect github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect + github.com/googleapis/gax-go/v2 v2.11.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect + github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 // indirect github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 // indirect github.com/hashicorp/consul-server-connection-manager v0.1.4 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-bexpr v0.1.2 // indirect + github.com/hashicorp/go-connlimit v0.3.0 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-memdb v1.3.4 // indirect github.com/hashicorp/go-msgpack v1.1.5 // indirect + github.com/hashicorp/go-msgpack/v2 v2.0.0 // indirect github.com/hashicorp/go-netaddrs v0.1.0 // indirect + github.com/hashicorp/go-plugin v1.4.5 // indirect + github.com/hashicorp/go-raftchunking v0.7.0 // indirect github.com/hashicorp/go-retryablehttp v0.6.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect + github.com/hashicorp/go-syslog v1.0.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/hashicorp/hcp-scada-provider v0.2.3 // indirect + github.com/hashicorp/hcp-sdk-go v0.61.0 // indirect + github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect + github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 // indirect github.com/hashicorp/raft v1.5.0 // indirect github.com/hashicorp/raft-autopilot v0.1.6 // indirect + github.com/hashicorp/raft-boltdb/v2 v2.2.2 // indirect + github.com/hashicorp/raft-wal v0.4.1 // indirect + github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 // indirect + github.com/hashicorp/vault/api v1.8.3 // indirect + github.com/hashicorp/vault/api/auth/gcp v0.3.0 // indirect + github.com/hashicorp/vault/sdk v0.7.0 // indirect github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 // indirect + github.com/imdario/mergo v0.3.15 // indirect github.com/itchyny/timefmt-go v0.1.5 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.16.7 // indirect github.com/magiconair/properties v1.8.7 // 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.17 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/miekg/dns v1.1.50 // indirect + github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.0 // indirect github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 // indirect + github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect + github.com/mitchellh/pointerstructure v1.2.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/patternmatcher v0.5.0 // indirect github.com/moby/sys/sequential v0.5.0 // indirect github.com/moby/term v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/morikuni/aec v1.0.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oklog/run v1.0.0 // indirect + github.com/oklog/ulid v1.3.1 // indirect github.com/oklog/ulid/v2 v2.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc4 // indirect github.com/opencontainers/runc v1.1.8 // indirect + github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pierrec/lz4 v2.6.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect + github.com/segmentio/fasthash v1.0.3 // indirect github.com/sirupsen/logrus v1.9.3 // indirect + github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/stretchr/objx v0.5.0 // indirect github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect + go.etcd.io/bbolt v1.3.7 // indirect + go.mongodb.org/mongo-driver v1.11.0 // indirect + go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/otel v1.16.0 // indirect + go.opentelemetry.io/otel/metric v1.16.0 // indirect + go.opentelemetry.io/otel/sdk v1.16.0 // indirect + go.opentelemetry.io/otel/sdk/metric v0.39.0 // indirect + go.opentelemetry.io/otel/trace v1.16.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect + go.uber.org/atomic v1.9.0 // indirect golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect golang.org/x/net v0.17.0 // indirect + golang.org/x/oauth2 v0.8.0 // indirect golang.org/x/sync v0.3.0 // indirect golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect + google.golang.org/api v0.126.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect google.golang.org/protobuf v1.31.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/ini.v1 v1.66.2 // indirect + gopkg.in/square/go-jose.v2 v2.5.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.26.2 // indirect + k8s.io/apimachinery v0.26.2 // indirect + k8s.io/client-go v0.26.2 // indirect + k8s.io/klog/v2 v2.90.1 // indirect + k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect + k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 // indirect + sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect ) replace ( diff --git a/test/integration/consul-container/go.sum b/test/integration/consul-container/go.sum index be31c2f43ab27..1cbb9315f5bc9 100644 --- a/test/integration/consul-container/go.sum +++ b/test/integration/consul-container/go.sum @@ -13,14 +13,32 @@ cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKV cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= +cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y= +cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -57,29 +75,44 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.156 h1:K4N91T1+RlSlx+t2dujeDviy4ehSGVjEltluDgmeHS4= +github.com/aliyun/alibaba-cloud-sdk-go v1.62.156/go.mod h1:Api2AkmMgGaSUAhmk76oaFObkoeCPc/bKAqcyplPODs= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e h1:QEF07wC0T1rKkctt1RINW/+RMTVmiwxETico2l3gxJA= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.9/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= +github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.44.289 h1:5CVEjiHFvdiVlKPBzv0rjG4zH/21W/onT18R5AH/qx0= github.com/aws/aws-sdk-go v1.44.289/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/benbjohnson/immutable v0.4.0 h1:CTqXbEerYso8YzVPxmWxh2gnoRQbbB9X1quUC8+vGZA= +github.com/benbjohnson/immutable v0.4.0/go.mod h1:iAr8OjJGLnLmVUr9MZ/rz4PWUy6Ouc2JLYuMArmvAJM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= +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.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -98,6 +131,7 @@ github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= @@ -108,16 +142,23 @@ github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 h1:/inchEIKaYC1Akx+H+g github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= +github.com/coreos/etcd v3.3.27+incompatible h1:QIudLb9KeBsE5zyYxd1mjzRSkzLg9Wf9QlRwFgd6oTA= +github.com/coreos/etcd v3.3.27+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-oidc v2.1.0+incompatible h1:sdJrfw8akMnCuUlaZU3tE/uYXFgfqom8DBE9so9EBsM= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU= +github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf h1:GOPo6vn/vTN+3IwZBvXX0y5doJfSC7My0cdzelyOCsQ= +github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.3.1 h1:vjmkvJt/IV27WXPyYQpAh4bRyWJc5Y435D17XQ9QU5A= -github.com/deckarep/golang-set/v2 v2.3.1/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= @@ -126,10 +167,15 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= +github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= @@ -139,12 +185,21 @@ github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9 github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= +github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= +github.com/frankban/quicktest v1.13.0 h1:yNZif1OkDfNoDfb9zZa9aXIpejNR4F23Wely0c+Qdqk= +github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -152,17 +207,92 @@ github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyM github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-ldap/ldap/v3 v3.1.10/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= +github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc= +github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= +github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= +github.com/go-openapi/runtime v0.25.0 h1:7yQTCdRbWhX8vnIjdzU8S00tBYf7Sg71EBeorlPHvhc= +github.com/go-openapi/runtime v0.25.0/go.mod h1:Ux6fikcHXyyob6LNWxtE96hWwjBPYF0DXgVFuMTneOs= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= +github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/strfmt v0.21.3 h1:xwhj5X6CjXEZZHMWy1zKJxvW9AfHC9pkyUjLvHtKG7o= +github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= +github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= +github.com/go-ozzo/ozzo-validation v3.6.0+incompatible h1:msy24VGS42fKO9K1vLz82/GeYW1cILu7Nuuj1N3BBkE= +github.com/go-ozzo/ozzo-validation v3.6.0+incompatible/go.mod h1:gsEKFIVnabGBt6mXmxK0MoFy+cZoTJY6mu5Ll3LVLBU= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -170,6 +300,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -185,13 +317,20 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -199,14 +338,20 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -214,15 +359,36 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= +github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/tcpproxy v0.0.0-20180808230851-dfa16c61dad2 h1:AtvtonGEH/fZK0XPNNBdB6swgy7Iudfx88wzyIpwqJ8= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= +github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= +github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= +github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 h1:1ZEjnveDe20yFa6lSkfdQZm5BR/b271n0MsB5R2L3us= +github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706/go.mod h1:1Cs8FlmD1BfSQXJGcFLSV5FuIx1AbJP+EJGdxosoS2g= github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 h1:wzWurXrxfSyG1PHskIZlfuXlTSCj1Tsyatp9DtaasuY= github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69/go.mod h1:svUZZDvotY8zTODknUePc6mZ9pX8nN0ViGwWcUSOBEA= github.com/hashicorp/consul-server-connection-manager v0.1.4 h1:wrcSRV6WGXFBNpNbN6XsdoGgBOyso7ZbN5VaWPEX1jY= @@ -236,30 +402,57 @@ github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-connlimit v0.3.0 h1:oAojHGjFxUTTTA8c5XXnDqWJ2HLuWbDiBPTpWvNzvqM= +github.com/hashicorp/go-connlimit v0.3.0/go.mod h1:OUj9FGL1tPIhl/2RCfzYHrIiWj+VVPGNyVPnUX8AqS0= github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0/go.mod h1:xvb32K2keAc+R8DSFG2IwDcydK9DBQE+fGA5fsw6hSk= github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= +github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-msgpack v1.1.5 h1:9byZdVjKTe5mce63pRVNP1L7UAmdHOTEMGehn6KvJWs= github.com/hashicorp/go-msgpack v1.1.5/go.mod h1:gWVc3sv/wbDmR3rQsj1CAktEZzoz1YNK9NfGLXJ69/4= +github.com/hashicorp/go-msgpack/v2 v2.0.0 h1:c1fiLq1LNghmLOry1ipGhvLDi+/zEoaEP2JrE1oFJ9s= +github.com/hashicorp/go-msgpack/v2 v2.0.0/go.mod h1:JIxYkkFJRDDRSoWQBSh7s9QAVThq+82iWmUpmE4jKak= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-netaddrs v0.1.0 h1:TnlYvODD4C/wO+j7cX1z69kV5gOzI87u3OcUinANaW8= github.com/hashicorp/go-netaddrs v0.1.0/go.mod h1:33+a/emi5R5dqRspOuZKO0E+Tuz5WV1F84eRWALkedA= +github.com/hashicorp/go-plugin v1.4.3/go.mod h1:5fGEH17QVwTTcR0zV7yhDPLLmFX9YSZ38b18Udy6vYQ= +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-raftchunking v0.7.0 h1:APNMnCXmTOhumkFv/GpJIbq7HteWF7EnGZ3875lRN0Y= +github.com/hashicorp/go-raftchunking v0.7.0/go.mod h1:Dg/eBOaJzE0jYKNwNLs5IA5j0OSmL5HoCUiMy3mDmrI= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.6.6/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-retryablehttp v0.6.7 h1:8/CAEZt/+F7kR7GevNHulKkUjLht3CPmn7egmhieNKo= github.com/hashicorp/go-retryablehttp v0.6.7/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6 h1:W9WN8p6moV1fjKLkeqEgkAMu5rauy9QeYDAmIaPuuiA= +github.com/hashicorp/go-secure-stdlib/awsutil v0.1.6/go.mod h1:MpCPSPGLDILGb4JMm94/mMi3YysIqsXzGCzkEZjcjXg= +github.com/hashicorp/go-secure-stdlib/base62 v0.1.1/go.mod h1:EdWO6czbmthiwZ3/PUsDV+UD1D5IRU4ActiaWGwt0Yw= +github.com/hashicorp/go-secure-stdlib/mlock v0.1.1 h1:cCRo8gK7oq6A2L6LICkUZ+/a5rLiRXFMf1Qd4xSwxTc= +github.com/hashicorp/go-secure-stdlib/mlock v0.1.1/go.mod h1:zq93CJChV6L9QTfGKtfBxKqD7BqqXx5O04A/ns2p5+I= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.1/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 h1:om4Al8Oy7kCm/B86rLCLah4Dt5Aa0Fr5rYBG60OzwHQ= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6/go.mod h1:QmrqtbKuxxSWTN3ETMPuB+VtEiBJ/A9XhoYGv8E1uD8= +github.com/hashicorp/go-secure-stdlib/password v0.1.1/go.mod h1:9hH302QllNwu1o2TGYtSk8I8kTAN0ca1EHpwhm5Mmzo= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.1/go.mod h1:gKOamz3EwoIoJq7mlMIRBpVTAUn8qPCrEclOKKWhD3U= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1/go.mod h1:l8slYwnJA26yBz+ErHpp2IRCLr0vuOMGBORIz4rRiAs= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= @@ -267,8 +460,10 @@ github.com/hashicorp/go-syslog v1.0.0 h1:KaodqZuhUoZereWVIYmpUgZysurB1kBLX2j0MwM github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -277,47 +472,104 @@ github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+l github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/hcp-scada-provider v0.2.3 h1:AarYR+/Pcv+cMvPdAlb92uOBmZfEH6ny4+DT+4NY2VQ= +github.com/hashicorp/hcp-scada-provider v0.2.3/go.mod h1:ZFTgGwkzNv99PLQjTsulzaCplCzOTBh0IUQsPKzrQFo= +github.com/hashicorp/hcp-sdk-go v0.61.0 h1:x4hJ8SlLI5WCE8Uzcu4q5jfdOEz/hFxfUkhAdoFdzSg= +github.com/hashicorp/hcp-sdk-go v0.61.0/go.mod h1:xP7wmWAmdMxs/7+ovH3jZn+MCDhHRj50Rn+m7JIY3Ck= github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038 h1:n9J0rwVWXDpNd5iZnwY7w4WZyq53/rROeI7OVvLW8Ok= +github.com/hashicorp/hil v0.0.0-20200423225030-a18a1cd20038/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= +github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0 h1:kBpVVl1sl3MaSrs97e0+pDQhSrqJv9gVbSUrPpVfl1w= +github.com/hashicorp/net-rpc-msgpackrpc/v2 v2.0.0/go.mod h1:6pdNz0vo0mF0GvhwDG56O3N18qBrAz/XRIcfINfTbwo= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= github.com/hashicorp/raft v1.2.0/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= +github.com/hashicorp/raft v1.3.11/go.mod h1:J8naEwc6XaaCfts7+28whSeRvCqTd6e20BlCU3LtEO4= github.com/hashicorp/raft v1.5.0 h1:uNs9EfJ4FwiArZRxxfd/dQ5d33nV31/CdCHArH89hT8= github.com/hashicorp/raft v1.5.0/go.mod h1:pKHB2mf/Y25u3AHNSXVRv+yT+WAnmeTX0BwVppVQV+M= github.com/hashicorp/raft-autopilot v0.1.6 h1:C1q3RNF2FfXNZfHWbvVAu0QixaQK8K5pX4O5lh+9z4I= github.com/hashicorp/raft-autopilot v0.1.6/go.mod h1:Af4jZBwaNOI+tXfIqIdbcAnh/UyyqIMj/pOISIfhArw= github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= +github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qRd6nFJYYS6Iqnc/8HcUmko2/2Gw8qTFEmxDLii6W5I= +github.com/hashicorp/raft-boltdb v0.0.0-20220329195025-15018e9b97e0 h1:CO8dBMLH6dvE1jTn/30ZZw3iuPsNfajshWoJTnVc5cc= +github.com/hashicorp/raft-boltdb/v2 v2.2.2 h1:rlkPtOllgIcKLxVT4nutqlTH2NRFn+tO1wwZk/4Dxqw= +github.com/hashicorp/raft-boltdb/v2 v2.2.2/go.mod h1:N8YgaZgNJLpZC+h+by7vDu5rzsRgONThTEeUS3zWbfY= +github.com/hashicorp/raft-wal v0.4.1 h1:aU8XZ6x8R9BAIB/83Z1dTDtXvDVmv9YVYeXxd/1QBSA= +github.com/hashicorp/raft-wal v0.4.1/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 h1:O6tNk0s/arubLUbLeCyaRs5xGo9VwmbQazISY/BfPK4= +github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0/go.mod h1:We3fJplmALwK1VpjwrLuXr/4QCQHYMdnXLHmLUU6Ntg= +github.com/hashicorp/vault/api v1.8.0/go.mod h1:uJrw6D3y9Rv7hhmS17JQC50jbPDAZdjZoTtrCCxxs7E= +github.com/hashicorp/vault/api v1.8.3 h1:cHQOLcMhBR+aVI0HzhPxO62w2+gJhIrKguQNONPzu6o= +github.com/hashicorp/vault/api v1.8.3/go.mod h1:4g/9lj9lmuJQMtT6CmVMHC5FW1yENaVv+Nv4ZfG8fAg= +github.com/hashicorp/vault/api/auth/gcp v0.3.0 h1:taum+3pCmOXnNgEKHlQbmgXmKw5daWHk7YJrLPP/w8g= +github.com/hashicorp/vault/api/auth/gcp v0.3.0/go.mod h1:gnNBFOASYUaFunedTHOzdir7vKcHL3skWBUzEn263bo= +github.com/hashicorp/vault/sdk v0.6.0/go.mod h1:+DRpzoXIdMvKc88R4qxr+edwy/RvH5QK8itmxLiDHLc= +github.com/hashicorp/vault/sdk v0.7.0 h1:2pQRO40R1etpKkia5fb4kjrdYMx3BHklPxl1pxpxDHg= +github.com/hashicorp/vault/sdk v0.7.0/go.mod h1:KyfArJkhooyba7gYCKSq8v66QdqJmnbAxtV/OX1+JTs= +github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I= github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM= +github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/itchyny/gojq v0.12.12 h1:x+xGI9BXqKoJQZkr95ibpe3cdrTbY8D9lonrK433rcA= github.com/itchyny/gojq v0.12.12/go.mod h1:j+3sVkjxwd7A7Z5jrbKibgOLn0ZfLWkV+Awxr/pyzJE= github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE= github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -343,19 +595,31 @@ github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2EmQ4l5rM/4FEfDWcRD+abF5XlKShorW5LRoQ= +github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-testing-interface v1.14.0 h1:/x0XQ6h+3U3nAyk1yx+bHPURrKa9sVVvYbuqZ7pIAtI= github.com/mitchellh/go-testing-interface v1.14.0/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452 h1:hOY53G+kBFhbYFpRVxHl5eS7laP6B1+Cq+Z9Dry1iMU= github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ= +github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= +github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= +github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= @@ -365,27 +629,49 @@ github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWK github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid/v2 v2.1.0 h1:+9lhoxAP56we25tyYETBBY1YLA2SaoLvUFgrP2miPJU= github.com/oklog/ulid/v2 v2.1.0/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= +github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= github.com/opencontainers/runc v1.1.8 h1:zICRlc+C1XzivLc3nzE+cbJV4LIi8tib6YG0MqC6OqA= github.com/opencontainers/runc v1.1.8/go.mod h1:CbUumNnWCuTGFukNXahoo/RFBZvDAgRh/smNYNOhA50= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= +github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU= github.com/otiai10/copy v1.10.0 h1:znyI7l134wNg/wDktoVQPxPkgvhDfGCYUasey+h0rDQ= github.com/otiai10/copy v1.10.0/go.mod h1:rSaLseMUsZFFbsFGc7wCJnnkTAvdc5L6VWxPE4308Ww= github.com/otiai10/mint v1.5.1 h1:XaPLeE+9vGbuyEHem1JNk3bYc7KKqyI/na0/mLd/Kks= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM= +github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -395,6 +681,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= +github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -419,17 +707,32 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM= +github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= +github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -444,6 +747,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -451,8 +755,19 @@ github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 h1:xzABM9let0HLLq github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569/go.mod h1:2Ly+NIftZN4de9zRmENdYbvPQeaVIYKWpLFStLFEBgI= github.com/testcontainers/testcontainers-go v0.22.0 h1:hOK4NzNu82VZcKEB1aP9LO1xYssVFMvlfeuDW9JMmV0= github.com/testcontainers/testcontainers-go v0.22.0/go.mod h1:k0YiPa26xJCRUbUkYqy5rY6NGvSbVCeUBXCvucscBR4= +github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -460,31 +775,64 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= +go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= +go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= +go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= +go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= +go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s= +go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4= +go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo= +go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4= +go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE= +go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4= +go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI= +go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI= +go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs= +go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.19.0 h1:IVN6GR+mhC4s5yfcTbmzHYODqvWAp3ZedA2SJPI1Nnw= go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -511,7 +859,9 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -520,10 +870,13 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -555,10 +908,18 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= @@ -568,16 +929,30 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8= +golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= @@ -589,11 +964,14 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -617,16 +995,31 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -634,26 +1027,32 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -662,10 +1061,14 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190424220101-1e8e1cfdf96b/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -700,7 +1103,18 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E= @@ -725,12 +1139,29 @@ google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= +google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -752,6 +1183,7 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -761,11 +1193,40 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e h1:xIXmWJ303kJCuogpj0bHq+dcjcZHU+XFyc1I0Yl9cRg= +google.golang.org/genproto v0.0.0-20230726155614-23370e0ffb3e/go.mod h1:0ggbjUrZYpy1q+ANUS30SEoGZ53cdfwtbuG7Ptgy108= google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU= google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= +google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -778,12 +1239,25 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.57.2 h1:uw37EN34aMFFXB2QPW7Tq6tdTbind1GpRxw5aOX3a5k= google.golang.org/grpc v1.57.2/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -797,21 +1271,34 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= +gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= @@ -822,6 +1309,24 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ= +k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= +k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ= +k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/client-go v0.26.2 h1:s1WkVujHX3kTp4Zn4yGNFK+dlDXy1bAAkIl+cFAiuYI= +k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E= +k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk= +k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k= +sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/test/integration/consul-container/test/catalog/catalog_test.go b/test/integration/consul-container/test/catalog/catalog_test.go index 5be52792d8218..0c8e913c8fbed 100644 --- a/test/integration/consul-container/test/catalog/catalog_test.go +++ b/test/integration/consul-container/test/catalog/catalog_test.go @@ -12,9 +12,14 @@ import ( libtopology "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" "github.com/hashicorp/consul/internal/catalog/catalogtest" + rtest "github.com/hashicorp/consul/internal/resource/resourcetest" "github.com/hashicorp/consul/proto-public/pbresource" ) +var ( + cli = rtest.ConfigureTestCLIFlags() +) + func TestCatalog(t *testing.T) { t.Parallel() @@ -29,10 +34,10 @@ func TestCatalog(t *testing.T) { client := pbresource.NewResourceServiceClient(followers[0].GetGRPCConn()) t.Run("one-shot", func(t *testing.T) { - catalogtest.RunCatalogV2Beta1IntegrationTest(t, client) + catalogtest.RunCatalogV2Beta1IntegrationTest(t, client, cli.ClientOptions(t)...) }) t.Run("lifecycle", func(t *testing.T) { - catalogtest.RunCatalogV2Beta1LifecycleIntegrationTest(t, client) + catalogtest.RunCatalogV2Beta1LifecycleIntegrationTest(t, client, cli.ClientOptions(t)...) }) } diff --git a/testing/deployer/go.mod b/testing/deployer/go.mod index c7916a013c2ea..9a8f53a322aca 100644 --- a/testing/deployer/go.mod +++ b/testing/deployer/go.mod @@ -5,8 +5,8 @@ go 1.20 require ( github.com/google/go-cmp v0.5.9 github.com/hashicorp/consul-server-connection-manager v0.1.4 - github.com/hashicorp/consul/api v1.26.1 - github.com/hashicorp/consul/proto-public v0.5.1 + github.com/hashicorp/consul/api v1.24.0 + github.com/hashicorp/consul/proto-public v0.1.0 github.com/hashicorp/consul/sdk v0.15.0 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-hclog v1.5.0 diff --git a/testing/deployer/sprawl/boot.go b/testing/deployer/sprawl/boot.go index 3bbb9e864e87c..f749093fcea1b 100644 --- a/testing/deployer/sprawl/boot.go +++ b/testing/deployer/sprawl/boot.go @@ -182,7 +182,7 @@ func (s *Sprawl) assignIPAddresses() error { return fmt.Errorf("unknown network %q", addr.Network) } addr.IPAddress = net.IPByIndex(node.Index) - s.logger.Info("assign addr", "node", node.Name, "addr", addr.IPAddress) + s.logger.Info("assign addr", "node", node.Name, "addr", addr.IPAddress, "enabled", !node.Disabled) } } } @@ -260,8 +260,11 @@ func (s *Sprawl) initConsulServers() error { return fmt.Errorf("populateInitialConfigEntries[%s]: %w", cluster.Name, err) } - if err := s.populateInitialResources(cluster); err != nil { - return fmt.Errorf("populateInitialResources[%s]: %w", cluster.Name, err) + if cluster.EnableV2 { + // Resources are available only in V2 + if err := s.populateInitialResources(cluster); err != nil { + return fmt.Errorf("populateInitialResources[%s]: %w", cluster.Name, err) + } } if err := s.createAnonymousToken(cluster); err != nil { @@ -300,8 +303,8 @@ func (s *Sprawl) createFirstTime() error { return fmt.Errorf("createAllServiceTokens: %w", err) } - if err := s.registerAllServicesForDataplaneInstances(); err != nil { - return fmt.Errorf("registerAllServicesForDataplaneInstances: %w", err) + if err := s.syncAllServicesForDataplaneInstances(); err != nil { + return fmt.Errorf("syncAllServicesForDataplaneInstances: %w", err) } // We can do this ahead, because we've incrementally run terraform as @@ -368,8 +371,8 @@ func (s *Sprawl) preRegenTasks() error { return fmt.Errorf("createAllServiceTokens: %w", err) } - if err := s.registerAllServicesForDataplaneInstances(); err != nil { - return fmt.Errorf("registerAllServicesForDataplaneInstances: %w", err) + if err := s.syncAllServicesForDataplaneInstances(); err != nil { + return fmt.Errorf("syncAllServicesForDataplaneInstances: %w", err) } return nil diff --git a/testing/deployer/sprawl/catalog.go b/testing/deployer/sprawl/catalog.go index fdc95c9f68934..1a11665eaae84 100644 --- a/testing/deployer/sprawl/catalog.go +++ b/testing/deployer/sprawl/catalog.go @@ -21,6 +21,7 @@ import ( "github.com/hashicorp/consul/testing/deployer/util" ) +// registerAllServicesToAgents registers services in agent-ful mode func (s *Sprawl) registerAllServicesToAgents() error { for _, cluster := range s.topology.Clusters { if err := s.registerServicesToAgents(cluster); err != nil { @@ -30,10 +31,10 @@ func (s *Sprawl) registerAllServicesToAgents() error { return nil } -func (s *Sprawl) registerAllServicesForDataplaneInstances() error { +func (s *Sprawl) syncAllServicesForDataplaneInstances() error { for _, cluster := range s.topology.Clusters { - if err := s.registerServicesForDataplaneInstances(cluster); err != nil { - return fmt.Errorf("registerServicesForDataplaneInstances[%s]: %w", cluster.Name, err) + if err := s.syncServicesForDataplaneInstances(cluster); err != nil { + return fmt.Errorf("syncServicesForDataplaneInstances[%s]: %w", cluster.Name, err) } } return nil @@ -86,7 +87,7 @@ func (s *Sprawl) registerAgentService( } if svc.IsMeshGateway { - return nil // handled at startup time for agent-full, but won't be for agent-less + return nil // handled at startup time for agent-ful, but won't be for agent-less } var ( @@ -176,94 +177,137 @@ RETRY: return nil } -func (s *Sprawl) registerServicesForDataplaneInstances(cluster *topology.Cluster) error { +// syncServicesForDataplaneInstances register/deregister services in the given cluster +func (s *Sprawl) syncServicesForDataplaneInstances(cluster *topology.Cluster) error { identityInfo := make(map[topology.ServiceID]*Resource[*pbauth.WorkloadIdentity]) - for _, node := range cluster.Nodes { - if !node.RunsWorkloads() || len(node.Services) == 0 || node.Disabled { - continue - } - - if !node.IsDataplane() { - continue - } - - if err := s.registerCatalogNode(cluster, node); err != nil { - return fmt.Errorf("error registering virtual node: %w", err) - } - - for _, svc := range node.Services { - if node.IsV2() { - pending := serviceInstanceToResources(node, svc) + // registerServiceAtNode is called when node is not disabled + registerServiceAtNode := func(node *topology.Node, svc *topology.Service) error { + if node.IsV2() { + pending := serviceInstanceToResources(node, svc) - workloadID := topology.NewServiceID(svc.WorkloadIdentity, svc.ID.Namespace, svc.ID.Partition) - if _, ok := identityInfo[workloadID]; !ok { - identityInfo[workloadID] = pending.WorkloadIdentity - } + workloadID := topology.NewServiceID(svc.WorkloadIdentity, svc.ID.Namespace, svc.ID.Partition) + if _, ok := identityInfo[workloadID]; !ok { + identityInfo[workloadID] = pending.WorkloadIdentity + } - // Write workload - res, err := pending.Workload.Build() + // Write workload + res, err := pending.Workload.Build() + if err != nil { + return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.Workload.Resource.Id), err) + } + workload, err := s.writeResource(cluster, res) + if err != nil { + return err + } + // Write check linked to workload + for _, check := range pending.HealthStatuses { + check.Resource.Owner = workload.Id + res, err := check.Build() if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.Workload.Resource.Id), err) + return fmt.Errorf("error serializing resource %s: %w", util.IDToString(check.Resource.Id), err) } - workload, err := s.writeResource(cluster, res) - if err != nil { + if _, err := s.writeResource(cluster, res); err != nil { return err } - // Write check linked to workload - for _, check := range pending.HealthStatuses { - check.Resource.Owner = workload.Id - res, err := check.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(check.Resource.Id), err) - } - if _, err := s.writeResource(cluster, res); err != nil { - return err - } + } + // maybe write destinations + if pending.Destinations != nil { + res, err := pending.Destinations.Build() + if err != nil { + return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.Destinations.Resource.Id), err) } - // maybe write destinations - if pending.Destinations != nil { - res, err := pending.Destinations.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.Destinations.Resource.Id), err) - } - if _, err := s.writeResource(cluster, res); err != nil { - return err - } + if _, err := s.writeResource(cluster, res); err != nil { + return err } - if pending.ProxyConfiguration != nil { - res, err := pending.ProxyConfiguration.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.ProxyConfiguration.Resource.Id), err) - } - if _, err := s.writeResource(cluster, res); err != nil { - return err - } + } + if pending.ProxyConfiguration != nil { + res, err := pending.ProxyConfiguration.Build() + if err != nil { + return fmt.Errorf("error serializing resource %s: %w", util.IDToString(pending.ProxyConfiguration.Resource.Id), err) } - } else { - if err := s.registerCatalogServiceV1(cluster, node, svc); err != nil { - return fmt.Errorf("error registering service: %w", err) + if _, err := s.writeResource(cluster, res); err != nil { + return err } - if !svc.DisableServiceMesh { - if err := s.registerCatalogSidecarServiceV1(cluster, node, svc); err != nil { - return fmt.Errorf("error registering sidecar service: %w", err) - } + } + } else { + if err := s.registerCatalogServiceV1(cluster, node, svc); err != nil { + return fmt.Errorf("error registering service: %w", err) + } + if !svc.DisableServiceMesh { + if err := s.registerCatalogSidecarServiceV1(cluster, node, svc); err != nil { + return fmt.Errorf("error registering sidecar service: %w", err) } } } + return nil } - for _, identity := range identityInfo { - res, err := identity.Build() - if err != nil { - return fmt.Errorf("error serializing resource %s: %w", util.IDToString(identity.Resource.Id), err) + // deregisterServiceAtNode is called when node is disabled + deregisterServiceAtNode := func(node *topology.Node, svc *topology.Service) error { + if node.IsV2() { + // TODO: implement deregister services for v2 + panic("deregister services is not implemented for V2") + } else { + if err := s.deregisterCatalogServiceV1(cluster, node, svc); err != nil { + return fmt.Errorf("error deregistering service: %w", err) + } + if !svc.DisableServiceMesh { + if err := s.deregisterCatalogSidecarServiceV1(cluster, node, svc); err != nil { + return fmt.Errorf("error deregistering sidecar service: %w", err) + } + } } - if _, err := s.writeResource(cluster, res); err != nil { - return err + return nil + } + + var syncService func(node *topology.Node, svc *topology.Service) error + + for _, node := range cluster.Nodes { + if !node.RunsWorkloads() || len(node.Services) == 0 { + continue + } + + if !node.IsDataplane() { + continue + } + + // Register virtual node service first if node is not disabled + if !node.Disabled { + if err := s.registerCatalogNode(cluster, node); err != nil { + return fmt.Errorf("error registering virtual node: %w", err) + } + } + + // Register/deregister services on the node + for _, svc := range node.Services { + if !node.Disabled { + syncService = registerServiceAtNode + } else { + syncService = deregisterServiceAtNode + } + syncService(node, svc) + } + + // Deregister the virtual node if node is disabled + if node.Disabled { + if err := s.deregisterCatalogNode(cluster, node); err != nil { + return fmt.Errorf("error deregistering virtual node: %w", err) + } } } if cluster.EnableV2 { + for _, identity := range identityInfo { + res, err := identity.Build() + if err != nil { + return fmt.Errorf("error serializing resource %s: %w", util.IDToString(identity.Resource.Id), err) + } + if _, err := s.writeResource(cluster, res); err != nil { + return err + } + } + for id, svcData := range cluster.Services { svcInfo := &Resource[*pbcatalog.Service]{ Resource: &pbresource.Resource{ @@ -311,6 +355,16 @@ func (s *Sprawl) registerCatalogNode( return s.registerCatalogNodeV1(cluster, node) } +func (s *Sprawl) deregisterCatalogNode( + cluster *topology.Cluster, + node *topology.Node, +) error { + if node.IsV2() { + panic("deregister V2 node is not implemented") + } + return s.deregisterCatalogNodeV1(cluster, node) +} + func (s *Sprawl) registerCatalogNodeV2( cluster *topology.Cluster, node *topology.Node, @@ -413,6 +467,82 @@ RETRY: return nil } +func (s *Sprawl) deregisterCatalogNodeV1( + cluster *topology.Cluster, + node *topology.Node, +) error { + if !node.IsDataplane() { + panic("called wrong method type") + } + + var ( + client = s.clients[cluster.Name] + logger = s.logger.With("cluster", cluster.Name) + ) + + dereg := &api.CatalogDeregistration{ + Node: node.PodName(), + Address: node.LocalAddress(), + } + if cluster.Enterprise { + dereg.Partition = node.Partition + } + + // deregister synthetic node +RETRY: + if _, err := client.Catalog().Deregister(dereg, nil); err != nil { + if isACLNotFound(err) { + time.Sleep(50 * time.Millisecond) + goto RETRY + } + return fmt.Errorf("error deregistering virtual node %s: %w", node.ID(), err) + } + + logger.Info("virtual node removed", + "node", node.ID(), + ) + + return nil +} + +func (s *Sprawl) deregisterCatalogServiceV1( + cluster *topology.Cluster, + node *topology.Node, + svc *topology.Service, +) error { + if !node.IsDataplane() { + panic("called wrong method type") + } + if node.IsV2() { + panic("don't call this") + } + + var ( + client = s.clients[cluster.Name] + logger = s.logger.With("cluster", cluster.Name) + ) + + dereg := &api.CatalogDeregistration{ + Node: node.PodName(), + ServiceID: svc.ID.Name, + } +RETRY: + if _, err := client.Catalog().Deregister(dereg, nil); err != nil { + if isACLNotFound(err) { + time.Sleep(50 * time.Millisecond) + goto RETRY + } + return fmt.Errorf("error deregistering service %s at node %s: %w", svc.ID, node.ID(), err) + } + + logger.Info("dataplane service removed", + "service", svc.ID, + "node", node.ID(), + ) + + return nil +} + func (s *Sprawl) registerCatalogServiceV1( cluster *topology.Cluster, node *topology.Node, @@ -449,6 +579,50 @@ RETRY: return nil } +func (s *Sprawl) deregisterCatalogSidecarServiceV1( + cluster *topology.Cluster, + node *topology.Node, + svc *topology.Service, +) error { + if !node.IsDataplane() { + panic("called wrong method type") + } + if svc.DisableServiceMesh { + panic("not valid") + } + if node.IsV2() { + panic("don't call this") + } + + var ( + client = s.clients[cluster.Name] + logger = s.logger.With("cluster", cluster.Name) + ) + + pid := svc.ID + pid.Name += "-sidecar-proxy" + dereg := &api.CatalogDeregistration{ + Node: node.PodName(), + ServiceID: pid.Name, + } + +RETRY: + if _, err := client.Catalog().Deregister(dereg, nil); err != nil { + if isACLNotFound(err) { + time.Sleep(50 * time.Millisecond) + goto RETRY + } + return fmt.Errorf("error deregistering service %s to node %s: %w", svc.ID, node.ID(), err) + } + + logger.Info("dataplane sidecar service removed", + "service", pid, + "node", node.ID(), + ) + + return nil +} + func (s *Sprawl) registerCatalogSidecarServiceV1( cluster *topology.Cluster, node *topology.Node, diff --git a/testing/deployer/topology/compile.go b/testing/deployer/topology/compile.go index beaace3e145b1..148968d6aeaf3 100644 --- a/testing/deployer/topology/compile.go +++ b/testing/deployer/topology/compile.go @@ -273,7 +273,7 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error n.Index = nextIndex nextIndex++ - n.Images = c.Images.OverrideWith(n.Images.ChooseConsul(c.Enterprise)).ChooseNode(n.Kind) + n.Images = c.Images.OverrideWith(n.Images).ChooseNode(n.Kind) n.Cluster = c.Name n.Datacenter = c.Datacenter diff --git a/testing/deployer/topology/images.go b/testing/deployer/topology/images.go index 318154c5822c0..ba20ba17d8c75 100644 --- a/testing/deployer/topology/images.go +++ b/testing/deployer/topology/images.go @@ -8,12 +8,8 @@ import ( ) type Images struct { - // Consul is the image used for creating the container, - // Use ChooseConsul() to control which image (ConsulCE or ConsulEnterprise) assign to Consul - Consul string `json:",omitempty"` - // ConsulCE sets the CE image - ConsulCE string `json:",omitempty"` - // ConsulEnterprise sets the ent image + Consul string `json:",omitempty"` + ConsulCE string `json:",omitempty"` ConsulEnterprise string `json:",omitempty"` Envoy string Dataplane string @@ -98,7 +94,6 @@ func (i Images) ChooseNode(kind NodeKind) Images { return i } -// ChooseConsul controls which image assigns to Consul func (i Images) ChooseConsul(enterprise bool) Images { if enterprise { i.Consul = i.ConsulEnterprise diff --git a/version/VERSION b/version/VERSION index ee017091ff37b..3cf57a7b61c64 100644 --- a/version/VERSION +++ b/version/VERSION @@ -1 +1 @@ -1.18.0-dev +1.17.1-dev diff --git a/website/content/docs/architecture/catalog/v1.mdx b/website/content/docs/architecture/catalog/v1.mdx new file mode 100644 index 0000000000000..f461ee119f586 --- /dev/null +++ b/website/content/docs/architecture/catalog/v1.mdx @@ -0,0 +1,37 @@ +--- +layout: docs +page_title: v1 Catalog API +description: Learn about version 1 of the Consul catalog, including what Consul servers record when they register a service. +--- + +# v1 Catalog API + +This topic provides conceptual information about version 1 (v1) of the Consul catalog API. The catalog tracks registered services and their locations for both service discovery and service mesh use cases. + +For more information about the information returned when querying the catalog, including filtering options when querying the catalog for a list of nodes, services, or gateways, refer to the [`/catalog` endpoint reference in the HTTP API documentation](/consul/api-docs/catalog). + +## Introduction + +Consul tracks information about registered services through its catalog API. This API records user-defined information about the external services, such as their partitions and required health checks. It also records information that Consul assigns for its own operations, such as an ID for each service instance and the [Raft indices](/consul/docs/architecture/consensus) when the instance is registered and modified. + +Consul uses v1 of the catalog API by default. Consul v1.17.0 and later ships with version 2 (v2) of the catalog API. V2 is intended for testing and development purposes. V1 and V2 of the catalog APIs cannot run concurrently in a Consul deployment. There is no migration path between catalog versions. For more information, refer to [Consul v2 Catalog API](/consul/docs/architecture/catalog/v2). + +## Catalog structure + +When Consul registers a service instance using the v1 catalog API, it records the following information about each instance: + +| v1 Catalog field | Description | Source | +| :--------------- | :---------- | :----- | +| ID | A unique identifier for a service instance. | Defined by user in [service definition](/consul/docs/services/configuration/services-configuration-reference#id). | +| Node | The connection point where the service is available. | On VMs, defined by user.

On Kubernetes, computed by Consul according to [Kubernetes Nodes](https://kubernetes.io/docs/concepts/architecture/nodes/). | +| Address | The registered address of the service instance. | Defined by user in [service definition](/consul/docs/services/configuration/services-configuration-reference#address). | +| Tagged Addresses | User-defined labels for addresses. | Defined by user in [service definition](/consul/docs/services/configuration/services-configuration-reference#tagged_addresses). | +| NodeMeta | User-defined metadata about the node. | Defined by user | +| Datacenter | The name of the datacenter the service is registered in. | Defined by user | +| Service | The name of the service Consul registers the service instance under. | Defined by user | +| Agent Check | The health checks defined for a service instance managed by a Consul client agent. | Computed by Consul | +| Health Checks | The health checks defined for the service. Refer to [define health checks](/consul/docs/services/usage/checks) for more information. | Defined by user | +| Partition | The name of the admin partition the service is registered in. Refer to [admin partitions](/consul/docs/enterprise/admin-partitions) for more information. | Defined by user | +| Locality | Region and availability zone of the service. Refer to [`locality`](/consul/docs/agent/config/config-files#locality) for more information. | Defined by user | + +Depending on the configuration entries or custom resource definitions you apply to your Consul installation, additional information such as [proxy default behavior](/consul/docs/connect/config-entries/proxy-defaults) is automatically recorded to the catalog for services. You can return this information using the [`/catalog` HTTP API endpoint](/consul/api-docs/catalog). diff --git a/website/content/docs/architecture/catalog/v2.mdx b/website/content/docs/architecture/catalog/v2.mdx new file mode 100644 index 0000000000000..c18255fa9ee3b --- /dev/null +++ b/website/content/docs/architecture/catalog/v2.mdx @@ -0,0 +1,106 @@ +--- +layout: docs +page_title: v2 Catalog API +description: Learn about version 2 of the Consul catalog, which uses GAMMA specified resources. Learn how the v2 catalog corresponds to the v1 catalog and Kubernetes resources. +--- + +# v2 Catalog API + + +The v2 catalog API is in a beta release for testing and development purposes. Do not use the v2 catalog or multi-port services in secure production environments. + + +This topic provides conceptual information about version 2 (v2) of the Consul catalog API. The catalog tracks registered services and their locations for both service discovery and service mesh use cases + +Consul supports the v2 catalog for service mesh use cases on Kubernetes deployments only. For more information about Consul’s default catalog, refer to [v1 Catalog API](/consul/docs/architecture/catalog/v1). + +## Introduction + +When Consul registers services, it records [user-defined and Consul-assigned information](/consul/docs/architecture/catalog/v1#catalog-structure). To determine a service’s identity, v1 of the catalog API records the following information: + +- IDs of the specific _service instances_ that are registered +- Locations of the _nodes_ the instances run on +- Names of the _services_ the instances are associated with + +This information enables Consul to associate service names with the individual instances and their unique network addresses, and it is essential to Consul’s service discovery and service mesh operations. + +The [Consul v1 catalog API](/consul/docs/architecture/catalog/v1) was designed prior to the introduction of Consul’s service mesh features. Communication in Consul’s service mesh is secured through Consul's ACL system, which requires that a Kubernetes ServiceAccount resource match the Service name. As a result, only one service can represent a service instance in the v1 catalog. + +The v2 catalog API aligns more closely with the [Kubernetes Gateway API's GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/), enabling functionality such as associating Kubernetes Pods with multiple Kubernetes Services and allowing Services and Pods registered with Consul to have multiple ports. For more information about how the differences between the catalog API impacts Consul operations, refer to [changes to Consul's existing architecture](#changes-to-consul-s-existing-architecture). + +The v2 catalog API is available alongside the existing v1 catalog API, but the catalogs cannot be used simultaneously. The v2 catalog is disabled by default. This beta release is for testing and development purposes only. We do not recommend implementing v2 in production environments or migrating to v2 until the API is generally available. + +## Catalog structure + +Consul v1.17 introduces a new version of the catalog API designed to bridge differences between the Consul and Kubernetes data models. The v2 catalog API still tracks services and nodes for Consul, but replaces service instances with _workloads_ and _workload identites_, which belong to different catalog groups. + +Traffic permissions are part of the `auth` group, and the [`TrafficPermissions` CRD](/consul/docs/k8s/multiport/reference/trafficpermissions) configures permissions according to an `identityName` that corresponds to the other resource in the `auth` group, workload identity. + +The [`HTTPRoute`](/consul/docs/k8s/multiport/reference/httproute), [`GRPCRoute`](/consul/docs/k8s/multiport/reference/grpcroute), and [`TCPRoute`](/consul/docs/k8s/multiport/reference/tcproute) CRDS are part of the `mesh` group, but they include `type` blocks that use a `group.groupVersion.kind` syntax to reference Consul services. Because a service is part of the `catalog` group, these CRDs refer to services using `catalog.v2beta1.Service`. + +The following table describes resources in the v2 catalog, including their `group`, how they compare to the v1 catalog and Kubernetes resources, and whether they are created by Kubernetes or computed by Consul when it registers a service. + +| Catalog v2 resource | Catalog v2 `group` | Description | Catalog v1 analogue | Kubernetes analogue | Source | +| :------------------ | :-------- | :---------- | :--------------------------- | :--------------------------- | :----- | +| Service | `catalog` | The name of the service Consul registers a workload under. | Service | [Kubernetes Service](https://kubernetes.io/docs/concepts/services-networking/service/) | Created by Kubernetes | +| Node | `catalog` | The address of the Consul node where the workload runs. | Node | [Kubernetes Node](https://kubernetes.io/docs/concepts/architecture/nodes/) | Computed by Consul | +| Workload | `catalog` | An application instance running in a set of one or more Pods scheduled according to a Kubernetes Workload resource such as a Deployment or StatefulSet. | Service instance | [Kubernetes Pod](https://kubernetes.io/docs/concepts/workloads/pods/) | Created by Kubernetes | +| Workload identity | `auth` | Provides a distinct identity for a workload to assume. Each workload identity is tied to an Envoy proxy. This identity is used when Consul generates mTLS certificates. | Service name | [Kubernetes Service Accounts](https://kubernetes.io/docs/concepts/security/service-accounts/) | Created by Kubernetes | +| Service endpoint | Maps services to workload addresses and endpoints. | None | [Kubernetes Endpoints](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/endpoints-v1/) | Computed by Consul | +| Health status | `catalog` | A resource for reporting the health status of a workload. | Service instance health status | [PodStatus](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodStatus) | Created by Kubernetes | +| Health check | None | A resource for defining the health checks for a workload. | [Service instance health check](/consul/docs/services/usage/checks) | [Liveness, Readiness, and Startup Probes](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes) | Created by Kubernetes | +| Proxy configuration | `mesh` | Represents a configuration for a sidecar or gateway proxy. | `Proxy` field in service definition | None | Created by Kubernetes or user CRD | +| Destinations | `catalog` | Represents explicit service upstreams. When using the v1 catalog, these upstreams are configured in Helm chart as [Upstream Service annotations](/consul/docs/k8s/annotations-and-labels#consul-hashicorp-com-connect-service-upstreams) | [Proxy Configuration](/consul/docs/connect/proxies/envoy#envoy-proxy-configuration-for-service-mesh) | None | Created by Kubernetes | +| Traffic permissions | `auth` | Enables L4 traffic authorization according to workload identity instead of service identity. | [Service intentions](/consul/docs/connect/intentions) | None | Created by user CRD | + +You can also use the `consul resource` command to return information about resources using the `group.groupVersion.kind` syntax. Refer to [`consul resource`](/consul/docs/k8s/multiport/reference/resource-command) for more information. + +## Changes to Consul’s existing architecture + +The change in data models introduced by the v2 Catalog API impacts several aspects of Consul’s operations. + +### Traffic permissions resource replaces service intentions + +The most significant change to Consul’s architecture and operations when using the v2 catalog structure is the introduction of the traffic permissions resource. This resource replaces the service intentions configuration entry, and enables authorized service-to-service communication for both L4 and L7 applications. + +For more information about this resource, including example configurations, refer to [Traffic permissions configuration reference](/consul/docs/k8s/multiport/reference/trafficpermissions). + +### HTTPRoute, GRPCRoute, and TCPRoute resources for traffic management + +You can configure traffic management behavior such as service splitting in an `HTTPRoute`, `GRPCRoute`, or `TCPRoute` resource. In the v1 catalog, this behavior is defined in dedicated configuration entries. For examples, refer to [service splitter configuration entry reference](/consul/docs/connect/config-entries/service-splitter#examples). + +For more information about these resource, including specifications and example configurations, refer to [HTTPRoute resource configuration reference](/consul/docs/k8s/multiport/reference/httproute), [GRPCRoute resource configuration reference](/consul/docs/k8s/multiport/reference/grpcroute), and [TCPRoute resource configuration reference](/consul/docs/k8s/multiport/reference/tcproute). + +### New proxy configuration resource + +In the v1 catalog, a service’s sidecar proxy and its behavior is [defined in the `Proxy` field of the service definition](/consul/docs/services/usage/define-services). You can also separately [define a service mesh proxy](/consul/docs/connect/proxies/deploy-service-mesh-proxies) and [configure proxy defaults](/consul/docs/connect/config-entries/proxy-defaults). + +In the v2 catalog, the `ProxyConfiguration` resource configures a workload's sidecar proxy behavior according to Consul workload identity. Refer to [ProxyConfiguration resource configuration reference](/consul/docs/k8s/multiport/reference/proxyconfiguration) for more information. + +## Constraints and limitations + +Be aware of the following constraints and technical limitations on the v2 catalog API: + +- The v2 catalog API only supports deployments using [Consul dataplanes](/consul/docs/connect/dataplane) instead of client agents. Consul on Kubernetes uses dataplanes by default. +- The v1 and v2 catalog APIs cannot run concurrently. +- The Consul UI does not support the v2 catalog API in this release. You must disable the UI in the Helm chart in order to use the v2 catalog API. +- HCP Consul does not support the v2 catalog API in this release. You cannot [link a self-managed cluster to HCP Consul](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. +- We do not recommend updating existing clusters to enable the v2 catalog in this release. Instead, deploy a new Consul cluster and [enable the v2 catalog in the Helm chart](/consul/docs/k8s/multiport/configure#enable-the-v2-catalog). + +## Guidance + +The following resources are available to help you use the v2 catalog API: + +### Usage documentation + +- [Multi-port services overview](/consul/docs/k8s/multiport) +- [Configure multi-port services](/consul/docs/k8s/multiport/configure) + +### Reference documentation + +- [`consul resource` CLI command](/consul/docs/k8s/multiport/reference/resource-command) +- [GRPCRoute configuration reference](/consul/docs/k8s/multiport/reference/grpcroute) +- [HTTPRoute configuration reference](/consul/docs/k8s/multiport/reference/httproute) +- [ProxyConfiguration configuration reference](/consul/docs/k8s/multiport/reference/proxyconfiguration) +- [TCPRoute configuration reference](/consul/docs/k8s/multiport/reference/tcproute) +- [TrafficPermissions configuration reference](/consul/docs/k8s/multiport/reference/trafficpermissions) diff --git a/website/content/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig.mdx b/website/content/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig.mdx index 2fa35a75521e1..816550a786770 100644 --- a/website/content/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig.mdx +++ b/website/content/docs/connect/gateways/api-gateway/configuration/gatewayclassconfig.mdx @@ -28,8 +28,8 @@ The following outline shows how to format the configurations in the `GatewayClas * [`grpc`](#consul-ports-grpc): integer | optional * [`http`](#consul-ports-http): integer | optional * [`scheme`](#consul-scheme): string | optional -* [`copyAnnotations`](#copyAnnotations): object | optional - * [`service`](#copyAnnotations-service): array of strings | optional +* [`copyAnnotations`](#copyannotations): object | optional + * [`service`](#copyannotations-service): array of strings | optional * [`deployment`](#deployment): object | optional * [`defaultInstances`](#deployment-defaultinstances): integer | optional * [`maxInstances`](#deployment-maxinstances): integer | optional @@ -38,9 +38,9 @@ The following outline shows how to format the configurations in the `GatewayClas * [`consulAPIGateway`](#image-consulapigateway): string | optional * [`envoy`](#image-envoy): string | optional * [`logLevel`](#loglevel): string | optional -* [`matchPrivilegedContainerPorts`](#matchPrivilegedContainerPorts): integer | optional +* [`mapPrivilegedContainerPorts`](#mapprivilegedcontainerports): integer | optional * [`nodeSelector`](#nodeselector): string | optional -* [`openshiftSCCName`](#openshiftSCCName): string | optional +* [`openshiftSCCName`](#openshiftsccname): string | optional * [`serviceType`](#servicetype): string | optional * [`useHostPorts`](#usehostports): boolean | optional @@ -154,8 +154,8 @@ You can specify the following strings: * `debug` * `trace` -### matchPrivilegedContainerPorts -Specifies a value that Consul adds to privileged ports defined in the gateway. Privileged ports are port numbers less than 1024 and some platforms, such as Red Hat OpenShift, explicitly configure Kubernetes to avoid running containers on privileged ports. The total value of the configured port number and the `matchPriviledgedContainerPorts` value must not exceed 65535, which is the highest possible TCP port number allowed. +### mapPrivilegedContainerPorts +Specifies a value that Consul adds to privileged ports defined in the gateway. Privileged ports are port numbers less than 1024 and some platforms, such as Red Hat OpenShift, explicitly configure Kubernetes to avoid running containers on privileged ports. The total value of the configured port number and the `mapPriviledgedContainerPorts` value must not exceed 65535, which is the highest possible TCP port number allowed. for gateway containers * Type: Integer * Required: optional diff --git a/website/content/docs/enterprise/index.mdx b/website/content/docs/enterprise/index.mdx index a8ff184784073..86f57794c158f 100644 --- a/website/content/docs/enterprise/index.mdx +++ b/website/content/docs/enterprise/index.mdx @@ -187,4 +187,4 @@ Consul Enterprise feature availability can change depending on your server and c | [Traffic rate limiting for services](/consul/docs/connect/manage-traffic/limit-request-rates) | ✅ | ✅ | ✅ | - + \ No newline at end of file diff --git a/website/content/docs/k8s/helm.mdx b/website/content/docs/k8s/helm.mdx index 34bda9400cf23..12e6077f36066 100644 --- a/website/content/docs/k8s/helm.mdx +++ b/website/content/docs/k8s/helm.mdx @@ -134,6 +134,10 @@ Use these links to navigate to a particular top-level stanza. - `vault` ((#v-global-secretsbackend-vault)) + - `vaultNamespace` ((#v-global-secretsbackend-vault-vaultnamespace)) (`string: ""`) - Vault namespace (optional). This sets the Vault namespace for the `vault.hashicorp.com/namespace` + agent annotation and [Vault Connect CA namespace](/consul/docs/connect/ca/vault#namespace). + To override one of these values individually, see `agentAnnotations` and `connectCA.additionalConfig`. + - `enabled` ((#v-global-secretsbackend-vault-enabled)) (`boolean: false`) - Enabling the Vault secrets backend will replace Kubernetes secrets with referenced Vault secrets. - `consulServerRole` ((#v-global-secretsbackend-vault-consulserverrole)) (`string: ""`) - The Vault role for the Consul server. @@ -235,7 +239,6 @@ Use these links to navigate to a particular top-level stanza. { "connect": [{ "ca_config": [{ - "namespace": "my-vault-ns", "leaf_cert_ttl": "36h" }] }] @@ -288,6 +291,8 @@ Use these links to navigate to a particular top-level stanza. - `secretKey` ((#v-global-gossipencryption-secretkey)) (`string: ""`) - The key within the Kubernetes secret or Vault secret key that holds the gossip encryption key. + - `logLevel` ((#v-global-gossipencryption-loglevel)) (`string: ""`) - Override global log verbosity level for gossip-encryption-autogenerate-job pods. One of "trace", "debug", "info", "warn", or "error". + - `recursors` ((#v-global-recursors)) (`array: []`) - A list of addresses of upstream DNS servers that are used to recursively resolve DNS queries. These values are given as `-recursor` flags to Consul servers and clients. Refer to [`-recursor`](/consul/docs/agent/config/cli-flags#_recursor) for more details. @@ -302,6 +307,8 @@ Use these links to navigate to a particular top-level stanza. authority (optional) and server and client certificates. This setting is required for [Cluster Peering](/consul/docs/connect/cluster-peering/k8s). + - `logLevel` ((#v-global-tls-loglevel)) (`string: ""`) - Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + - `enableAutoEncrypt` ((#v-global-tls-enableautoencrypt)) (`boolean: false`) - If true, turns on the auto-encrypt feature on clients and servers. It also switches consul-k8s-control-plane components to retrieve the CA from the servers via the API. Requires Consul 1.7.1+. @@ -383,6 +390,8 @@ Use these links to navigate to a particular top-level stanza. for all Consul and consul-k8s-control-plane components. This requires Consul >= 1.4. + - `logLevel` ((#v-global-acls-loglevel)) (`string: ""`) - Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + - `bootstrapToken` ((#v-global-acls-bootstraptoken)) - A Kubernetes or Vault secret containing the bootstrap token to use for creating policies and tokens for all Consul and consul-k8s-control-plane components. If `secretName` and `secretKey` are unset, a default secret name and secret key are used. If the secret is populated, then @@ -414,7 +423,7 @@ Use these links to navigate to a particular top-level stanza. - `secretKey` ((#v-global-acls-replicationtoken-secretkey)) (`string: null`) - The key within the Kubernetes or Vault secret that holds the replication token. - - `resources` ((#v-global-acls-resources)) (`map`) - The resource requests (CPU, memory, etc.) for the server-acl-init and server-acl-init-cleanup pods. + - `resources` ((#v-global-acls-resources)) (`map`) - The resource requests (CPU, memory, etc.) for the server-acl-init and server-acl-init-cleanup pods. This should be a YAML map corresponding to a Kubernetes [`ResourceRequirements``](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#resourcerequirements-v1-core) object. @@ -440,7 +449,7 @@ Use these links to navigate to a particular top-level stanza. - `secretName` ((#v-global-acls-partitiontoken-secretname)) (`string: null`) - The name of the Vault secret that holds the partition token. - - `secretKey` ((#v-global-acls-partitiontoken-secretkey)) (`string: null`) - The key within the Vault secret that holds the partition token. + - `secretKey` ((#v-global-acls-partitiontoken-secretkey)) (`string: null`) - The key within the Vault secret that holds the parition token. - `tolerations` ((#v-global-acls-tolerations)) (`string: ""`) - tolerations configures the taints and tolerations for the server-acl-init and server-acl-init-cleanup jobs. This should be a multi-line string matching the @@ -465,6 +474,14 @@ Use these links to navigate to a particular top-level stanza. "sample/annotation2": "bar" ``` + - `argocd` ((#v-global-argocd)) - If argocd.enabled is set to true, following annotations are added to + job - server-acl-init-job + annotations - + argocd.argoproj.io/hook: Sync + argocd.argoproj.io/hook-delete-policy: HookSucceeded + + - `enabled` ((#v-global-argocd-enabled)) (`boolean: false`) + - `enterpriseLicense` ((#v-global-enterpriselicense)) - This value refers to a Kubernetes or Vault secret that you have created that contains your enterprise license. It is required if you are using an enterprise binary. Defining it here applies it to your cluster once a leader @@ -484,7 +501,7 @@ Use these links to navigate to a particular top-level stanza. - `enabled` ((#v-global-federation-enabled)) (`boolean: false`) - If enabled, this datacenter will be federation-capable. Only federation via mesh gateways is supported. Mesh gateways and servers will be configured to allow federation. - Requires `global.tls.enabled`, `connectInject.enabled`, and one of + Requires `global.tls.enabled`, `connectInject.enabled`, and one of `meshGateway.enabled` or `externalServers.enabled` to be true. Requires Consul 1.8+. @@ -508,7 +525,7 @@ Use these links to navigate to a particular top-level stanza. from the one used by the Consul Service Mesh. Please refer to the [Kubernetes Auth Method documentation](/consul/docs/security/acl/auth-methods/kubernetes). - If `externalServers.enabled` is set to true, `global.federation.k8sAuthMethodHost` and + If `externalServers.enabled` is set to true, `global.federation.k8sAuthMethodHost` and `externalServers.k8sAuthMethodHost` should be set to the same value. You can retrieve this value from your `kubeconfig` by running: @@ -518,6 +535,8 @@ Use these links to navigate to a particular top-level stanza. -o jsonpath="{.clusters[?(@.name=='')].cluster.server}" ``` + - `logLevel` ((#v-global-federation-loglevel)) (`string: ""`) - Override global log verbosity level for the create-federation-secret-job pods. One of "trace", "debug", "info", "warn", or "error". + - `metrics` ((#v-global-metrics)) - Configures metrics for Consul service mesh - `enabled` ((#v-global-metrics-enabled)) (`boolean: false`) - Configures the Helm chart’s components @@ -622,6 +641,21 @@ Use these links to navigate to a particular top-level stanza. ] ``` + - `experiments` ((#v-global-experiments)) (`array: []`) - Consul feature flags that will be enabled across components. + Supported feature flags: + * `resource-apis`: + _**Danger**_! This feature is under active development. It is not + recommended for production use. Setting this flag during an + upgrade could risk breaking your Consul cluster. + If this flag is set, Consul components will use the + V2 resources APIs for all operations. + + Example: + + ```yaml + experiments: [ "resource-apis" ] + ``` + ### server ((#h-server)) - `server` ((#v-server)) - Server, when enabled, configures a server cluster to run. This should @@ -632,6 +666,8 @@ Use these links to navigate to a particular top-level stanza. Consul server cluster. If you're running Consul externally and want agents within Kubernetes to join that cluster, this should probably be false. + - `logLevel` ((#v-server-loglevel)) (`string: ""`) - Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + - `image` ((#v-server-image)) (`string: null`) - The name of the Docker image (including any tag) for the containers running Consul server agents. @@ -1004,7 +1040,7 @@ Use these links to navigate to a particular top-level stanza. ... ``` - - `auditLogs` ((#v-server-auditlogs)) - Added in Consul 1.8, the audit object allow users to enable auditing + - `auditLogs` ((#v-server-auditlogs)) - Added in Consul 1.8, the audit object allow users to enable auditing and configure a sink and filters for their audit logs. Please refer to [audit logs](/consul/docs/enterprise/audit-logging) documentation for further information. @@ -1012,7 +1048,7 @@ Use these links to navigate to a particular top-level stanza. - `enabled` ((#v-server-auditlogs-enabled)) (`boolean: false`) - Controls whether Consul logs out each time a user performs an operation. global.acls.manageSystemACLs must be enabled to use this feature. - - `sinks` ((#v-server-auditlogs-sinks)) (`array`) - A single entry of the sink object provides configuration for the destination to which Consul + - `sinks` ((#v-server-auditlogs-sinks)) (`array`) - A single entry of the sink object provides configuration for the destination to which Consul will log auditing events. Example: @@ -1027,7 +1063,7 @@ Use these links to navigate to a particular top-level stanza. rotate_duration: 24h rotate_max_files: 15 rotate_bytes: 25165824 - + ``` The sink object supports the following keys: @@ -1124,7 +1160,7 @@ Use these links to navigate to a particular top-level stanza. This address must be reachable from the Consul servers. Please refer to the [Kubernetes Auth Method documentation](/consul/docs/security/acl/auth-methods/kubernetes). - If `global.federation.enabled` is set to true, `global.federation.k8sAuthMethodHost` and + If `global.federation.enabled` is set to true, `global.federation.k8sAuthMethodHost` and `externalServers.k8sAuthMethodHost` should be set to the same value. You could retrieve this value from your `kubeconfig` by running: @@ -1145,6 +1181,8 @@ Use these links to navigate to a particular top-level stanza. the resources necessary for a Consul client on every Kubernetes node. This _does not_ require `server.enabled`, since the agents can be configured to join an external cluster. + - `logLevel` ((#v-client-loglevel)) (`string: ""`) - Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + - `image` ((#v-client-image)) (`string: null`) - The name of the Docker image (including any tag) for the containers running Consul client agents. @@ -1742,6 +1780,10 @@ Use these links to navigate to a particular top-level stanza. These CRDs can clash with existing Gateway API CRDs if they are already installed in your cluster. If this setting is false, you will need to install the Gateway API CRDs manually. + - `manageNonStandardCRDs` ((#v-connectinject-apigateway-managenonstandardcrds)) (`boolean: false`) - Enables Consul on Kubernets to manage only the non-standard CRDs used for Gateway API. If manageExternalCRDs is true + then all CRDs will be installed; otherwise, if manageNonStandardCRDs is true then only TCPRoute, GatewayClassConfig and MeshService + will be installed. + - `managedGatewayClass` ((#v-connectinject-apigateway-managedgatewayclass)) - Configuration settings for the GatewayClass installed by Consul on Kubernetes. - `nodeSelector` ((#v-connectinject-apigateway-managedgatewayclass-nodeselector)) (`string: null`) - This value defines [`nodeSelector`](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) @@ -1772,6 +1814,8 @@ Use these links to navigate to a particular top-level stanza. - external-dns.alpha.kubernetes.io/hostname ``` + - `resources` ((#v-connectinject-apigateway-managedgatewayclass-resources)) (`map`) - The resource settings for Pods handling traffic for Gateway API. + - `deployment` ((#v-connectinject-apigateway-managedgatewayclass-deployment)) - This value defines the number of pods to deploy for each Gateway as well as a min and max number of pods for all Gateways - `defaultInstances` ((#v-connectinject-apigateway-managedgatewayclass-deployment-defaultinstances)) (`integer: 1`) @@ -1780,6 +1824,14 @@ Use these links to navigate to a particular top-level stanza. - `minInstances` ((#v-connectinject-apigateway-managedgatewayclass-deployment-mininstances)) (`integer: 1`) + - `openshiftSCCName` ((#v-connectinject-apigateway-managedgatewayclass-openshiftsccname)) (`string: restricted-v2`) - The name of the OpenShift SecurityContextConstraints resource to use for Gateways. + Only applicable if `global.openshift.enabled` is true. + + - `mapPrivilegedContainerPorts` ((#v-connectinject-apigateway-managedgatewayclass-mapprivilegedcontainerports)) (`integer: 0`) - This value defines the amount we will add to privileged container ports on gateways that use this class. + This is useful if you don't want to give your containers extra permissions to run privileged ports. + Example: The gateway listener is defined on port 80, but the underlying value of the port on the container + will be the 80 + the number defined below. + - `serviceAccount` ((#v-connectinject-apigateway-serviceaccount)) - Configuration for the ServiceAccount created for the api-gateway component - `annotations` ((#v-connectinject-apigateway-serviceaccount-annotations)) (`string: null`) - This value defines additional annotations for the client service account. This should be formatted as a multi-line @@ -1791,8 +1843,6 @@ Use these links to navigate to a particular top-level stanza. "sample/annotation2": "bar" ``` - - `resources` ((#v-connectinject-apigateway-resources)) (`map`) - The resource settings for Pods handling traffic for Gateway API. - - `cni` ((#v-connectinject-cni)) - Configures consul-cni plugin for Consul Service mesh services - `enabled` ((#v-connectinject-cni-enabled)) (`boolean: false`) - If true, then all traffic redirection setup uses the consul-cni plugin. @@ -1926,7 +1976,7 @@ Use these links to navigate to a particular top-level stanza. - `imageConsul` ((#v-connectinject-imageconsul)) (`string: null`) - The Docker image for Consul to use when performing Connect injection. Defaults to global.image. - - `logLevel` ((#v-connectinject-loglevel)) (`string: ""`) - Override global log verbosity level. One of "debug", "info", "warn", or "error". + - `logLevel` ((#v-connectinject-loglevel)) (`string: ""`) - Sets the `logLevel` for the `consul-dataplane` sidecar and the `consul-connect-inject-init` container. When set, this value overrides the global log verbosity level. One of "debug", "info", "warn", or "error". - `serviceAccount` ((#v-connectinject-serviceaccount)) @@ -2148,6 +2198,8 @@ Use these links to navigate to a particular top-level stanza. This setting is required for [Cluster Peering](/consul/docs/connect/cluster-peering/k8s). Requirements: consul 1.6.0+ if using `global.acls.manageSystemACLs``. + - `logLevel` ((#v-meshgateway-loglevel)) (`string: ""`) - Override global log verbosity level for mesh-gateway-deployment pods. One of "trace", "debug", "info", "warn", or "error". + - `replicas` ((#v-meshgateway-replicas)) (`integer: 1`) - Number of replicas for the Deployment. - `wanAddress` ((#v-meshgateway-wanaddress)) - What gets registered as WAN address for the gateway. @@ -2311,6 +2363,8 @@ Use these links to navigate to a particular top-level stanza. - `enabled` ((#v-ingressgateways-enabled)) (`boolean: false`) - Enable ingress gateway deployment. Requires `connectInject.enabled=true`. + - `logLevel` ((#v-ingressgateways-loglevel)) (`string: ""`) - Override global log verbosity level for ingress-gateways-deployment pods. One of "trace", "debug", "info", "warn", or "error". + - `defaults` ((#v-ingressgateways-defaults)) - Defaults sets default values for all gateway fields. With the exception of annotations, defining any of these values in the `gateways` list will override the default values provided here. Annotations will @@ -2423,8 +2477,9 @@ Use these links to navigate to a particular top-level stanza. - `gateways` ((#v-ingressgateways-gateways)) (`array`) - Gateways is a list of gateway objects. The only required field for each is `name`, though they can also contain any of the fields in - `defaults`. Values defined here override the defaults except in the - case of annotations where both will be applied. + `defaults`. You must provide a unique name for each ingress gateway. These names + must be unique across different namespaces. + Values defined here override the defaults, except in the case of annotations where both will be applied. - `name` ((#v-ingressgateways-gateways-name)) (`string: ingress-gateway`) @@ -2440,6 +2495,8 @@ Use these links to navigate to a particular top-level stanza. - `enabled` ((#v-terminatinggateways-enabled)) (`boolean: false`) - Enable terminating gateway deployment. Requires `connectInject.enabled=true`. + - `logLevel` ((#v-terminatinggateways-loglevel)) (`string: ""`) - Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + - `defaults` ((#v-terminatinggateways-defaults)) - Defaults sets default values for all gateway fields. With the exception of annotations, defining any of these values in the `gateways` list will override the default values provided here. Annotations will @@ -2545,7 +2602,7 @@ Use these links to navigate to a particular top-level stanza. ### apiGateway ((#h-apigateway)) -- `apiGateway` ((#v-apigateway)) - [DEPRECATED] Use connectInject.apiGateway instead. This stanza will be removed with the release of Consul 1.17 +- `apiGateway` ((#v-apigateway)) - [DEPRECATED] Use connectInject.apiGateway instead. Configuration settings for the Consul API Gateway integration - `enabled` ((#v-apigateway-enabled)) (`boolean: false`) - When true the helm chart will install the Consul API Gateway controller @@ -2696,7 +2753,9 @@ Use these links to navigate to a particular top-level stanza. - `enabled` ((#v-telemetrycollector-enabled)) (`boolean: false`) - Enables the consul-telemetry-collector deployment - - `image` ((#v-telemetrycollector-image)) (`string: hashicorp/consul-telemetry-collector:0.0.1`) - The name of the Docker image (including any tag) for the containers running + - `logLevel` ((#v-telemetrycollector-loglevel)) (`string: ""`) - Override global log verbosity level. One of "trace", "debug", "info", "warn", or "error". + + - `image` ((#v-telemetrycollector-image)) (`string: hashicorp/consul-telemetry-collector:0.0.2`) - The name of the Docker image (including any tag) for the containers running the consul-telemetry-collector - `resources` ((#v-telemetrycollector-resources)) (`map`) - The resource settings for consul-telemetry-collector pods. diff --git a/website/content/docs/k8s/multiport/configure.mdx b/website/content/docs/k8s/multiport/configure.mdx index 8beaf8339d1cd..cbd781ad2dc01 100644 --- a/website/content/docs/k8s/multiport/configure.mdx +++ b/website/content/docs/k8s/multiport/configure.mdx @@ -18,18 +18,23 @@ This page describes the process for integrating a service that uses multiple por Registering multi-port services with Consul requires Kubernetes. Multi-port services are not supported on VM deployments. -The following software versions are required: +The following minimum versions are required: - Consul v1.17.0 -- `consul-k8s` CLI v1.3.0+ or `hashicorp/consul` Helm chart release v1.3.0+ +- `consul-k8s` CLI v1.3.0 or `hashicorp/consul` Helm chart release v1.3.0 +- `consul-dataplanes` v1.3.0 -For more information about upgrading versions for `consul-k8s` and Helm charts, refer to [Update the Consul K8s CLI](/consul/docs/k8s/upgrade/upgrade-cli) and [Upgrade Helm chart version](/consul/docs/k8s/upgrade#upgrade-helm-chart-version). +To install or update the `consul-k8s CLI`, refer to [install the latest version](/consul/docs/k8s/installation/install-cli#install-the-latest-version) or [upgrade the CLI](/consul/docs/k8s/upgrade/upgrade-cli#upgrade-the-cli). + +The required version of Consul dataplanes deploy automatically when using the latest version of `consul-k8s`. Dataplane version is configured manually when you [modify `imageConsulDataplane`](/consul/docs/k8s/helm#v-global-imageconsuldataplane) in the Helm chart. + +For more information about upgrading Helm charts, refer to [Upgrade Helm chart version](/consul/docs/k8s/upgrade#upgrade-helm-chart-version). There are additional requirements for service mesh proxies in transparent proxy mode. This mode enables queries through Kube DNS instead of Consul DNS over permissive mTLS settings. For more information about the steps to configure global settings and enable permissive mTLS mode before registering a service, refer to the [onboard services in transparent mode workflow](/consul/docs/k8s/connect/onboarding-tproxy-mode#workflow). ## Enable the v2 catalog -To enable the v2 catalog and its support for multi-port services, set `global.experiments: ["resource-apis"]` and `ui.enabled: false`. The following example includes these parameters in a Helm chart with minimal required configurations for the Consul installation: +To enable the v2 catalog and its support for multi-port services, set `global.experiments: ["resource-apis"]` and `ui.enabled: false`. The following example includes these parameters in a Helm chart with additional configurations for the Consul installation: @@ -37,10 +42,12 @@ To enable the v2 catalog and its support for multi-port services, set `global.ex global: enabled: true name: consul - image: hashicorp/consul:1.17.0-rc1 + image: hashicorp/consul:1.17.0 datacenter: dc1 tls: enabled: true + acls: + manageSystemACLs: true experiments: ["resource-apis"] server: enabled: true @@ -59,13 +66,7 @@ Then install Consul to your Kubernetes cluster using either the `consul-k8s` CLI -For platforms other than Mac OSX amd64, refer to [Install a previous version](/consul/docs/k8s/installation/install-cli#install-a-previous-version) for instructions on how to install a specific version of the `consul-k8s` CLI prior to running `consul-k8s install`. - ```shell-session -$ export VERSION=1.3.0-rc1 && \ - curl --location "https://releases.hashicorp.com/consul-k8s/${VERSION}/consul-k8s_${VERSION}_darwin_amd64.zip" --output consul-k8s-cli.zip -$ unzip -o consul-k8s-cli.zip -d ~/consul-k8s -$ export PATH=$PATH:$HOME/consul-k8s $ consul-k8s install -config-file=values.yaml ``` @@ -74,7 +75,7 @@ $ consul-k8s install -config-file=values.yaml ```shell-session -$ helm install consul hashicorp/consul --create-namespace --namespace consul --version 1.3.0-rc1 --values values.yaml +$ helm install consul hashicorp/consul --create-namespace --namespace consul --version 1.3.0 --values values.yaml ``` @@ -289,23 +290,23 @@ $ kubectl apply -f api.yaml -f web.yaml ## Configure traffic permissions -Consul uses traffic permissions to validate communication between services based on L4 identity. In the beta release of the v2 catalog API, traffic permissions allow all services by default. In order to verify that services function correctly on each port, create CRDs that deny traffic to each port. +Consul uses traffic permissions to validate communication between services based on L4 identity. When ACLs are enabled for the service mesh, traffic permissions deny all services by default. In order to allow traffic between the static client and the multi-port service, create CRDs that allow traffic to each port. The following examples create Consul CRDs that allow traffic to only one port of the multi-port service. Each resource separately denies `web` permission when it is a source of traffic to one of the services. These traffic permissions work with either method for defining a multi-port service. When following the instructions on this page, apply these permissions individually when you validate the ports. - + - + ```yaml apiVersion: auth.consul.hashicorp.com/v2beta1 kind: TrafficPermissions metadata: - name: web-to-api-port-deny + name: web-to-api spec: destination: identityName: api - action: deny + action: ACTION_ALLOW permissions: - sources: - identityName: web @@ -315,17 +316,17 @@ spec: - + ```yaml apiVersion: auth.consul.hashicorp.com/v2beta1 kind: TrafficPermissions metadata: - name: web-to-admin-port-deny + name: web-to-admin spec: destination: identityName: api - action: deny + action: ACTION_ALLOW permissions: - sources: - identityName: web @@ -347,57 +348,59 @@ api-5784b54bcc-tp98l 3/3 Running 0 6m55 web-6dcbd684bc-gk8n5 2/2 Running 0 6m55s ``` -Set environment variables to remember the pod name for the web workload for use in future commands. +Set environment variables to remember the pod name for the web workload for use in future commands. + + ```shell-session $ export WEB_POD=web-6dcbd684bc-gk8n5 ``` -### Validate both ports + + +### Apply traffic permissions -Use the `web` Pod's name to open a shell session and test the `api` service on port 80. +Use the `web` Pod's name to open a shell session and test the `api` service on both ports. When ACLs are enabled, these commands fail until you apply a traffic permissions resource. +Test the `api` service on port 80. + ```shell-session $ kubectl exec -it ${WEB_POD} -c web -- curl api:80 -hello world ``` Then test the `api` service on port 90. ```shell-session $ kubectl exec -it ${WEB_POD} -c web -- curl api:90 -hello world from 9090 admin ``` +Test the `api` service on port 80. + ```shell-session $ kubectl exec -it ${WEB_POD} -c web -- curl api:80 -hello world ``` Then test the `api-admin` service on port 90. ```shell-session -$ kubectl exec -it ${WEB_POD} -c web --namespace consul -- curl api-admin:90 -hello world from 9090 admin +$ kubectl exec -it ${WEB_POD} -c web -- curl api-admin:90 ``` -### Validate port 80 - -Apply the CRD to allow traffic to port 80 only: +Apply the CRD to allow traffic to port 80: ```shell-session -$ kubectl apply -f deny-90.yaml +$ kubectl apply -f allow-80.yaml ``` @@ -410,13 +413,6 @@ Then, open a shell session in the `web` container and test the `api` service on $ kubectl exec -it ${WEB_POD} -c web -- curl api:80 hello world ``` - -Test the `api` service on port 90. This command should fail, indicating that the traffic permission is in effect. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:90 -``` - @@ -428,27 +424,13 @@ $ kubectl exec -it ${WEB_POD} -c web -- curl api:80 hello world ``` -Test the `admin` service on port 90. This command should fail, indicating that the traffic permission is in effect. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api-admin:90 -``` - -Before testing the other port, remove the `TrafficPermissions` CRD. +Apply the CRD to allow traffic to port 90: ```shell-session -$ kubectl delete -f deny-90.yaml -``` - -### Validate port 90 - -Apply the CRD to allow traffic to port 90 only: - -```shell-session -$ kubectl apply -f deny-80.yaml +$ kubectl apply -f allow-90.yaml ``` @@ -462,12 +444,6 @@ $ kubectl exec -it ${WEB_POD} -c web -- curl api:90 hello world from 9090 admin ``` -Test the `api` service on port 80. This command should fail, indicating that the traffic permission is in effect. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:80 -``` - @@ -479,11 +455,16 @@ $ kubectl exec -it ${WEB_POD} -c web -- curl api-admin:90 hello world from 9090 admin ``` -Test the `api` service on port 80. This command should fail, indicating that the traffic permission is in effect. - -```shell-session -$ kubectl exec -it ${WEB_POD} -c web -- curl api:80 -``` - + +## Next steps + +After applying traffic permissions and validating service-to-service communication within your service mesh, you can manage traffic between multi-port services, filter traffic between ports based on L7 header information, or direct match HTTP query parameters to a specific port. + +Refer to the following pages for more information: + +- [Split traffic between services](/consul/docs/k8s/multiport/traffic-split) +- [gRPC route example: route traffic by matching header](/consul/docs/k8s/multiport/reference/httproute#route-traffic-by-matching-header) +- [HTTP route example: route traffic by matching header](/consul/docs/k8s/multiport/reference/httproute#route-traffic-by-matching-header) +- [HTTP route example: route traffic by matching header and query parameter](/consul/docs/k8s/multiport/reference/httproute#route-traffic-by-matching-header-and-query-parameter) \ No newline at end of file diff --git a/website/content/docs/k8s/multiport/index.mdx b/website/content/docs/k8s/multiport/index.mdx index 0cdc6fca92aa0..bd474ffec1205 100644 --- a/website/content/docs/k8s/multiport/index.mdx +++ b/website/content/docs/k8s/multiport/index.mdx @@ -1,10 +1,10 @@ --- layout: docs -page_title: Multi-port services for service mesh -description: Consul on Kubernetes supports multi-port services for both service discovery and service mesh scenarios. Learn about Consul’s v2 catalog changes to support multiple ports for a service running in a single container. +page_title: Multi-port services overview +description: Consul on Kubernetes supports multi-port services for both service discovery and service mesh scenarios. Learn how Consul’s v2 catalog supports multiple ports for a service running in a single container. --- -# Multi-port services for service mesh +# Multi-port services overview @@ -12,58 +12,55 @@ Multi-port services are part of a beta release. This documentation supports test -This topic describes changes to Consul's catalog that allow you to register a service with multiple ports on Kubernetes deployments. +This topic describes the process to register a service with multiple ports on Kubernetes deployments using the v2 catalog API. For information about the v2 catalog’s contents and structure, refer to [v2 catalog API](/consul/docs/architecture/catalog/v2). -## Introduction +## Workflow -When Consul registers services, v1 of its catalog API tracks the following information: +To use a multi-port service in Consul on Kubernetes deployments, complete the following steps: -- IDs of the specific _service instances_ that are registered -- Locations of the _nodes_ the instances run on -- Names of the _services_ the instances are associated with +1. Enable the v2 catalog with ACLs enabled. Add `global.experiments: ["resource-apis"]`, `ui.enabled: false`, and `manageSystemACLs: true` to a cluster's Helm chart before deploying Consul. +1. Use the `"consul.hashicorp.com/mesh-inject": "true"` annotation so that Consul registers the service automatically when Kubernetes deploys containers. +1. Configure traffic permissions. When ACLs are enabled, Consul denies all traffic by default. You can use the `TrafficPermissions` CRD to allow traffic to services. -This catalog API was designed prior to the introduction of Consul’s service mesh features. The service mesh uses Consul's ACL system, which requires a Kubernetes ServiceAccount resource to match the Service name. As a result, only one service can represent a Kubernetes Workload in the Consul catalog. +For an example configuration and instructions for each of the steps in this workflow, refer to [configure multi-port services](/consul/docs/k8s/multiport/configure). -Since then, the cloud networking needs for applications have evolved and the Consul catalog adapted to support workarounds for these needs. For example, [Kubernetes Pods with multiple ports](/consul/docs/k8s/connect#kubernetes-pods-with-multiple-ports) demonstrates how you can schedule a service with multiple ports so that Consul registers it in the catalog as distinct services with their own service instances. However, this workaround results in additional resource consumption because Consul requires that each service and port use their own proxy and Consul dataplane so that it can recognize them as distinct services. +### Advanced proxy and route configuration workflow -### Catalog API v2 beta +You can also configure Envoy proxies and sidecar behavior with the proxy configurations resource, and manage traffic between services at the L4 and L7 networking layers with the TCP, HTTP, and gRPC route resources. After you [configure multi-port services](/consul/docs/k8s/multiport/configure), complete the following steps: -Consul v1.17 introduces a new version of the catalog API designed to bridge differences between the Consul and Kubernetes data models. The v2 catalog API still tracks services and nodes for Consul, but replaces service instances with _workloads_ and _workload identites_. +1. Define the resource's behavior in a custom resource definition (CRD). For specifications and example configurations, refer to the [configuration reference](#reference-documentation) for each resource. +1. Apply the resource to your cluster. -- `Workload` is an application instance running in a set of one or more Pods scheduled according to a Kubernetes Workload resource such as a Deployment or StatefulSet. It is similar to [Kubernetes Workloads](https://kubernetes.io/docs/concepts/workloads/). -- `WorkloadIdentities` provide a distinct identity for a Workload to assume in a Kubernetes cluster. They are similar to [Kubernetes Service Accounts](https://kubernetes.io/docs/concepts/security/service-accounts/). +For an example configuration and instructions for each of the steps in this workflow, refer to [split TCP service traffic between ports](/consul/docs/k8s/multiport/traffic-split). -This catalog structure enables Consul to associate a single Kubernetes Workload with multiple services in its catalog. +## Constraints and limitations -The v2 catalog API also tracks the following information about services when they are registered with Consul: +Be aware of the following constraints and technical limitations on using multi-port services and the v2 catalog API: -- `ServiceEndpoints` maps services to workload addresses and endpoints. This resource is computed by Consul. -- `HealthStatus` is a resource for reporting the health status of a workload. -- `HealthCheck` is a resource for defining the health checks for a workload. -- `ProxyConfiguration` represents a configuration for a sidecar or gateway proxy, similar to the `Proxy` field in the current service definition. -- `Destinations` represents explicit service upstreams. -- `TrafficPermissions` is a replacement for the `ServiceIntentions` custom resource definition (CRD). Traffic permissions replace service intentions for all services in the v2 catalog, which enables L4 traffic authorization according to workload identity instead of service identity. +- Multi-port services are available for deployments using [Consul dataplanes](/consul/docs/connect/dataplane) instead of client agents. Consul on Kubernetes uses dataplanes by default. +- When running the v2 catalog for multi-port services, you cannot run the v1 catalog API at the same time. +- The Consul UI does not support multi-port services in this release. You must disable the UI in the Helm chart in order to use multi-port services. +- HCP Consul does not support multi-port services in this release. You cannot [link a self-managed cluster to HCP Consul](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. +- We do not recommend updating existing clusters to enable the v2 catalog in this release. To register multi-port services, deploy a new Consul cluster that enables the v2 catalog. -The v2 catalog API is available alongside the existing v1 catalog API, but the catalogs cannot be used simultaneously. The v2 catalog is disabled by default. This beta release is for testing and development purposes only. We do not recommend implementing v2 in production environments or migrating to v2 until the API is generally available. +## Guidance -## Workflow +The following resources are available to help you use multi-port services: -To use a multi-port service in Consul on Kubernetes deployments, complete the following steps: +### Concepts -1. Enable the v2 catalog. Add `global.experiments: ["resource-apis"]` and `ui.enabled: false` to a cluster's Helm chart before deploying Consul. -1. Use the `"consul.hashicorp.com/mesh-inject": "true"` annotation so that Consul registers the service automatically when Kubernetes deploys containers. -1. Configure traffic permissions. In the beta release, services registered to the v2 catalog allow all traffic by default. You can use the `TrafficPermissions` CRD to deny traffic to individual services for testing purposes. -1. Validate multi-port functionality. Send test traffic to each port to confirm that traffic is authorized and routed correctly. +- [v2 catalog API](/consul/docs/architecture/catalog/v2) -For an example configuration and instructions for each of the steps in this workflow, refer to [configure multi-port services](/consul/docs/k8s/multiport/configure). +### Usage documentation -## Constraints and limitations +- [Configure multi-port services](/consul/docs/k8s/multiport/configure) +- [Split TCP traffic between multi-port services](/consul/docs/k8s/multiport/traffic-split) -Be aware of the following constraints and technical limitations on using multi-port services and the v2 catalog API: +### Reference documentation -- The v2 catalog API beta does not support connections with client agents. It is only available for Kubernetes deployments, which use [Consul dataplanes](/consul/docs/connect/dataplane) instead of client agents. -- The v1 and v2 catalog APIs cannot run concurrently. -- The Consul UI does not support multi-port services or the v2 catalog API in this release. You must disable the UI in the Helm chart in order to use the v2 catalog API. -- HCP Consul does not support multi-port services or the v2 catalog API in this release. You cannot [link a self-managed cluster to HCP Consul](/hcp/docs/consul/self-managed) to access its UI or view observability metrics when it uses the v2 catalog. -- The v2 catalog API does not support ACLs in the beta release. -- We do not recommend updating existing clusters to enable the v2 catalog in this release. To use the v2 catalog, deploy a new Consul cluster. \ No newline at end of file +- [`consul resource` CLI command](/consul/docs/k8s/multiport/reference/resource-command) +- [`GRPCRoute` resource configuration reference](/consul/docs/k8s/multiport/reference/grpcroute) +- [`HTTPRoute` resource configuration reference](/consul/docs/k8s/multiport/reference/httproute) +- [`ProxyConfiguration` resource configuration reference](/consul/docs/k8s/multiport/reference/proxyconfiguration) +- [`TCPRoute` resource configuration reference](/consul/docs/k8s/multiport/reference/tcproute) +- [`TrafficPermissions` resource configuration reference](/consul/docs/k8s/multiport/reference/trafficpermissions) diff --git a/website/content/docs/k8s/multiport/reference/grpcroute.mdx b/website/content/docs/k8s/multiport/reference/grpcroute.mdx new file mode 100644 index 0000000000000..2373ff96a67d0 --- /dev/null +++ b/website/content/docs/k8s/multiport/reference/grpcroute.mdx @@ -0,0 +1,804 @@ +--- +layout: docs +page_title: GRPCRoute resource configuration reference +description: The GRPCRoute resource CRD configures L7 gRPC traffic behavior within the service mesh. GRPCRoute requires the v2 catalog API. Learn how to configure the GRPCRoute CRD with specifications and example configurations. +--- + +# GRPCRoute resource configuration reference + +This page provides reference information for the `GRPCRoute` resource, which defines L7 gRPC traffic within the service mesh. + +This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/catalog/v2). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog/v1). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/). + +## Configuration model + +The following list outlines field hierarchy, language-specific data types, and requirements in a gRPC route CRD. Click on a property name to view additional details, including default values. + +- [`apiVersion`](#apiversion): string | required | must be set to `mesh.consul.hashicorp.com/v2beta1` +- [`kind`](#kind): string | required | must be set to `GRPCRoute` +- [`metadata`](#metadata): map | required + - [`name`](#metadata-name): string | required + - [`namespace`](#metadata-namespace): string | optional +- [`spec`](#spec): map | required + - [`parentRefs`](#spec-parentrefs): map | required + - [`port`](#spec-parentrefs-port): string + - [`ref`](#spec-parentrefs-ref): string | required + - [`name`](#spec-parentrefs-ref-name): string + - [`type`](#spec-parentrefs-ref-type): map + - [`group`](#spec-parentrefs-ref-type): string + - [`groupVersion`](#spec-parentrefs-ref-type): string + - [`kind`](#spec-parentrefs-ref-type): string + - [`rules`](#spec-rules): map | required + - [`backendRefs`](#spec-rules-backendrefs): map + - [`backendRef`](#spec-rules-backendrefs-backendref): map + - [`datacenter`](#spec-rules-backendrefs-backendref-datacenter): string + - [`port`](#spec-rules-backendrefs-backendref-port): string + - [`ref`](#spec-rules-backendrefs-backendref-ref): map + - [`name`](#spec-rules-backendrefs-backendref-ref-name): string + - [`type`](#spec-rules-backendrefs-backendref-ref-type): map + - [`group`](#spec-rules-backendrefs-backendref-ref-type): string + - [`groupVersion`](#spec-rules-backendrefs-backendref-ref-type): string + - [`kind`](#spec-rules-backendrefs-backendref-ref-type): string + - [`filters`](#spec-rules-backendrefs-filters): map + - [`requestHeaderModifier`](#spec-rules-backendrefs-filters-requestheadermodifier): map + - [`add`](#spec-rules-backendrefs-filters-requestheadermodifier): map + - [`set`](#spec-rules-backendrefs-filters-requestheadermodifier): map + - [`remove`](#spec-rules-backendrefs-filters-requestheadermodifier): map + - [`responseHeaderModifier`](#spec-rules-backendrefs-filters-responseheadermodifier): map + - [`add`](#spec-rules-backendrefs-filters-responseheadermodifier): map + - [`set`](#spec-rules-backendrefs-filters-responseheadermodifier): map + - [`remove`](#spec-rules-backendrefs-filters-responseheadermodifier): map + - [`urlRewrite`](#spec-rules-backendrefs-filters-urlrewrite): map + - [`pathPrefix`](#spec-rules-backendrefs-filters-urlrewrite): string + - [`weight`](#spec-rules-backendrefs-weight): number | `1` + - [`filters`](#spec-rules-filters): map + - [`requestHeaderModifier`](#spec-rules-filters-requestheadermodifier): map + - [`add`](#spec-rules-filters-requestheadermodifier): map + - [`set`](#spec-rules-filters-requestheadermodifier): map + - [`remove`](#spec-rules-filters-requestheadermodifier): map + - [`responseHeaderModifier`](#spec-rules-filters-responseheadermodifier): map + - [`add`](#spec-rules-filters-responseheadermodifier): map + - [`set`](#spec-rules-filters-responseheadermodifier): map + - [`remove`](#spec-rules-filters-responseheadermodifier): map + - [`urlRewrite`](#spec-rules-filters-urlrewrite): map + - [`pathPrefix`](#spec-rules-filters-urlrewrite): string + - [`matches`](#spec-rules-matches): map + - [`headers`](#spec-rules-matches-headers): map + - [`name`](#spec-rules-matches-headers-name): string + - [`type`](#spec-rules-matches-headers-type): string + - [`value`](#spec-rules-matches-headers-value): string + - [`method`](#spec-rules-matches-method): map + - [`method`](#spec-rules-matches-method-method): string + - [`service`](#spec-rules-matches-method-service): string + - [`type`](#spec-rules-matches-method-type): string + - [`retries`](#spec-rules-retries): map + - [`number`](#spec-rules-retries-number): map + - [`value`](#spec-rules-retries-number): number + - [`onConditions`](#spec-rules-retries-onconditions): map of strings + - [`onConnectFailure`](#spec-rules-retries-onconnectfailure): boolean | `false` + - [`onStatusCodes`](#spec-rules-retries-onconditions): map of numbers + - [`timeouts`](#spec-rules-timeouts): map + - [`idle`](#spec-rules-timeouts-idle): string + - [`request`](#spec-rules-timeouts-request): string + +## Complete configuration + +When every field is defined, a gRPC route resource CRD has the following form: + +```yaml +apiVersion: mesh.consul.hashicorp.com/v2beta1 # required +kind: GRPCRoute # required +metadata: + name: + namespace: +spec: + parentRefs: + port: + - ref: + name: + type: + group: + groupVersion: + kind: + rules: + - backendRefs: + - backendRef: + datacenter: + port: "" + ref: + name: + type: + group: + groupVersion: + kind: + filters: + - requestHeaderModifier: + add: + name: + value: + - responseHeaderModifier: + set: + name: + value: + urlRewrite: + pathPrefix: + weight: 1 + filters: + requestHeaderModifier: + remove: + name: + value: + responseHeaderModifier: + add: + name: + value: + urlRewrite: + pathPrefix: + matches: + headers: + name: + type: + value: + method: + method: + service: + type: + retries: + number: + value: 1 + onConditions: ["cancelled", "unavailable"] + onConnectFailure: false + onStatusCodes: [400, 404] + timeouts: + idle: <1s> + request: <1s> +``` + +## Specification + +This section provides details about the fields you can configure in the `GRPCRoute` custom resource definition (CRD). + +### `apiVersion` + +Specifies the version of the Consul API for integrating with Kubernetes. The value must be `mesh.consul.hashicorp.com/v2beta1`. + +#### Values + +- Default: None +- This field is required. +- String value that must be set to `mesh.consul.hashicorp.com/v2beta1`. + +### `kind` + +Specifies the type of CRD to implement. Must be set to `GRPCRoute`. + +#### Values + +- Default: None +- This field is required. +- Data type: String value that must be set to `GRPCRoute`. + +### `metadata` + +Map that contains an arbitrary name for the CRD and the namespace it applies to. + +#### Values + +- Default: None +- Data type: Map + +### `metadata.name` + +Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information. + +#### Values + +- Default: None +- This field is required. +- Data type: String + +### `metadata.namespace` + +Specifies the namespace that the service resolver applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information. + +#### Values + +- Default: None +- Data type: String + +### `spec` + +Map that contains the details about the `GRPCRoute` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children. + +When using this CRD, the `spec` field closely resembles the `GRPCRoute` GAMMA resource. Refer to [GRPCRoute in the Kubernetes documentation](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.GRPCRoute). + +#### Values + +- Default: None +- This field is required. +- Data type: Map + +### `spec.parentRefs` + +Specifies the services and other resources to attach the route to. You can only define one `parentsRefs` configuration for each route. To attach the route to multiple resources, specify additional [`spec.parentRefs.ref`](#spec-parentrefs-ref) configurations in the `parentsRefs` block. You can only specify the name of one port for the route. Any resources that send traffic through the route use the same port. + +#### Values + +- Default: None +- This field is required. +- Data type: Map + +### `spec.parentRefs.port` + +Specifies the name of the port that the configuration applies to. + +#### Values + +- Default: None +- Data type: String + +### `spec.parentRefs.ref` + +Specifies the resource that the route attaches to. + +#### Values + +- Default: None +- Data type: Map + +### `spec.parentRefs.ref.name` + +Specifies the user-defined name of the resource that the configuration applies to. + +#### Values + +- Default: None +- Data type: String + +### `spec.parentRefs.ref.type` + +Specifies the type of resource that the configuration applies to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`. + +#### Values + +- Default: None +- Data type: Map containing the following parameters: + + | Parameter | Description | Data type | Default | + | :------------ | :------------------------------------------------------------------- | :-------- | :------- | + | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `kind` | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | + +### `spec.rules` + +Specifies rules for sidecar proxies to direct a service's gRPC traffic within the service mesh, including filtering, retry, and timeout behavior. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs` + +Specifies the Kubernetes Service backend to direct GRPC traffic to when a request matches the service described in [`spec.parentRefs`](#spec-parentrefs). The Service backend is the collection of endpoint IPs for the service. Refer to [the Kubernetes Gateway API specification](https://gateway-api.sigs.k8s.io/concepts/gamma/#an-overview-of-the-gateway-api-for-service-mesh) for more information about Service backends. + +When a valid Service backend cannot be reached and no additional filters apply, traffic that matches the rule returns a 500 status code. + +When different Service backends are specified in [`spec.rules.backendRefs.weight`](#spec-rules-backendrefs-weight) and one of the backends is invalid, Consul continues to apply the specified weights instead of adjusting the relative weights to exclude traffic to the invalid backend. For example, when traffic is configured in a 50-50 split between `api` and `admin` and no valid endpoints for `admin` can be reached, the 50% of traffic intended for `admin` returns with a 500 status code. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs.backendRef` + +Specifies an individual Service backend where matching requests should be sent. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs.backendRef.datacenter` + +Specifies the name of the Consul datacenter that registered the Service backend that the configuration routes traffic to. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.backendRefs.backendRef.port` + +Specifies the name of the port for the Consul service that the configuration routes traffic to. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.backendRefs.backendRef.ref` + +The Consul service that the configuration routes traffic to. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs.backendRef.ref.name` + +Specifies the user-defined name of the resource that the configuration routes traffic to. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.backendRefs.backendRef.ref.type` + +Specifies the type of resource that the configuration routes traffic to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`. + +#### Values + +- Default: None +- Data type: Map containing the following parameters: + + | Parameter | Description | Data type | Default | + | --- | --- | --- | --- | + | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `kind` | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | + +### `spec.rules.backendRefs.filters` + +Specifies filtering behavior for services configured in the same [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs.filters.requestHeaderModifier` + +Specifies a set of header modification rules applied to requests routed with the gRPC route resource. + +#### Values + +- Default: None +- Values: Object containing one or more fields that define header modification rules: + - `add`: Map of one or more key-value pairs. + - `set`: Map of one or more key-value pairs. + - `remove`: Map of one or more key-value pairs. + +The following table describes how to configure values for request headers: + +| Rule | Description | Type | +| --- | --- | --- | +| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | +| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | +| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | List of strings | + +##### Use variable placeholders + +For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. + +### `spec.rules.backendRefs.filters.responseHeaderModifier` + +Specifies a set of header modification rules applied to responses routed with the gRPC route resource. + +#### Values + +- Default: None +- Values: Object containing one or more fields that define header modification rules: + - `add`: Map of one or more key-value pairs. + - `set`: Map of one or more key-value pairs. + - `remove`: Map of one or more key-value pairs. + +The following table describes how to configure values for request headers: + +| Rule | Description | Type | +| --- | --- | --- | +| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | +| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | +| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | List of strings | + +##### Use variable placeholders + +For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. + +### `spec.rules.backendRefs.filters.urlRewrite` + +Specifies a path to modify the URL with when a request is forwarded. + +#### Values + +- Default: None +- Data type: Map containing the following parameter: + + | Parameter | Description | Data type | Default | + | :------------ | :------------------------------------------------------------------------------------------------- | --------- | ------- | + | `pathPrefix` | Specifies the path that is prepended to the URL. | String | None | + +### `spec.rules.backendRefs.weight` + +Specifies the proportion of requests routed to the specified service. + +This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. + +When this parameter is not specified, Consul defaults to `1`. + +#### Values + +- Default: `1` +- Data type: Integer + +### `spec.rules.filters` + +Specifies filtering behavior for all requests that match the service defined in [`spec.parentRefs`](#spec-parent-refs). + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.filters.requestHeaderModifier` + +Specifies a set of header modification rules applied to requests that match the service defined in [`spec.parentRefs`](#spec-parent-refs). + +#### Values + +- Default: None +- Values: Object containing one or more fields that define header modification rules: + - `add`: Map of one or more key-value pairs. + - `set`: Map of one or more key-value pairs. + - `remove`: Map of one or more key-value pairs. + +The following table describes how to configure values for request headers: + +| Rule | Description | Type | +| --- | --- | --- | +| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | +| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | +| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | List of strings | + +##### Use variable placeholders + +For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. + +### `spec.rules.filters.responseHeaderModifier` + +Specifies a set of header modification rules applied to responses from services matching [`spec.parentRefs`](#spec-parent-refs). + +#### Values + +- Default: None +- Values: Object containing one or more fields that define header modification rules: + - `add`: Map of one or more key-value pairs. + - `set`: Map of one or more key-value pairs. + - `remove`: Map of one or more key-value pairs. + +The following table describes how to configure values for request headers: + +| Rule | Description | Type | +| --- | --- | --- | +| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | +| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | Map of strings | +| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | List of strings | + +##### Use variable placeholders + +For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. + +### `spec.rules.filters.urlRewrite` + +Specifies a path to modify the URL with when a request matching [`spec.parentRefs`](#spec-parent-refs) is forwarded. + +#### Values + +- Default: None +- Data type: Map containing the following parameter: + + | Parameter | Description | Data type | Default | + | :------------ | :------------------------------------------------------------------------------------------------- | --------- | ------- | + | `pathPrefix` | Specifies a path to prepend to the URL when a request matching [`spec.parentRefs`](#spec-parent-refs) is forwarded. | String | None | + +### `spec.rules.matches` + +Specifies rules for matching traffic to services described in [`spec.parentRefs`](#spec-parent-refs) according to the request header or method. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.matches.headers` + +Specifies criteria for matching gRPC request headers. + +When [`spec.rules.matches.headers.value`] is specified multiple times, a request must match all of the specified values for the route to be selected. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.matches.headers.name` + +Specifies the name of a gRPC request header to match on. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.matches.headers.type` + +Specifies a type of match to perform on the gRPC request header. Supported match types include: unspecified, exact, regex, present, prefix, and suffix. + +#### Values + +- Default: None +- Data type: String that should match one of the following values: + + - `HEADER_MATCH_TYPE_UNSPECIFIED` + - `HEADER_MATCH_TYPE_EXACT` + - `HEADER_MATCH_TYPE_REGEX` + - `HEADER_MATCH_TYPE_PRESENT` + - `HEADER_MATCH_TYPE_PREFIX` + - `HEADER_MATCH_TYPE_SUFFIX` + +### `spec.rules.matches.headers.value` + +Specifies the value of the gRPC request header to match. When this field is specified multiple times, a request must match all of the specified values for the route to be selected. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.matches.method` + +Specifies criteria for matching a service and a gRPC request method. When configuring this field, either [`spec.rules.matches.method.method`](#spec-rules-matches-method-method) or [`spec.rules.matches.method.service`](#spec-rules-matches-method-service) must be a non-empty string. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.matches.method.method` + +Specifies the value of the method to match. When empty or omitted, all methods match. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.matches.method.service` + +Specifies the value of the service to match. When empty or omitted, all services match. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.matches.method.type` + +Specifies a type of match to perform on the gRPC request method. Supported match types include: unspecified, exact, and regex. + +#### Values + +- Default: None +- Data type: String that should match one of the following values: + + - `GRPC_METHOD_MATCH_TYPE_UNSPECIFIED` + - `GRPC_METHOD_MATCH_TYPE_EXACT` + - `GRPC_METHOD_MATCH_TYPE_REGEX` + +### `spec.rules.retries` + +Specifies retry logic for routing gRPC traffic. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.retries.number` + +Specifies the number of retries to attempt when a request fails. + +#### Values + +- Default: None +- Data type: Map that contains the following parameter: + + | Parameter | Description | Data type | Default | + | :-------- | :------------------------------------------- | --------- | ------- | + | `value` | Specifies the number of retries to attempt. | Integer | None | + +### `spec.rules.retries.onConditions` + +Specifies Envoy conditions that cause an automatic retry attempt. + +#### Values + +- Default: None +- Data type: Map of strings + +### `spec.rules.retries.onConnnectFailure` + +Enables an automatic retry attempt when a connection failure error occurs. + +#### Values + +- Default: `false` +- Data type: Boolean + +### `spec.rules.retries.onStatusCodes` + +Specifies the response status codes that are eligible for retry attempts. + +#### Values + +- Default: None +- Data type: Map of integers + +### `spec.rules.timeouts` + +Specifies timeout logic when routing gRPC traffic + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.timeouts.idle` + +Specifies the total amount of time permitted for the request stream to be idle before a timeout occurs. + +This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.timeouts.request` + +Specifies the total amount of time spent processing the entire downstream request, including retries, before triggering a timeout. + +This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`. + +#### Values + +- Default: None +- Data type: String + +## Examples + +The following examples demonstrate common GRPCRoute CRD configuration patterns for specific use cases. + +### Split gRPC traffic between two ports + +The following example splits traffic for the `api` service. GRPC traffic for services registered to the Consul catalog that are available at the `api-workload` port is split so that 50% of the traffic routes to the service at the `api-workload` port and 50% routes to the service at the `admin-workload` port. + +```yaml +apiVersion: mesh.consul.hashicorp.com/v2beta1 +kind: GRPCRoute +metadata: + name: api-split + namespace: default +spec: + parentRefs: + - ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api-workload" + rules: + - backendRefs: + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api-workload" + weight: 50 + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "admin-workload" + weight: 50 +``` + +### Route traffic by matching header + +The following example routes gRPC traffic for the `api` service according to its header. GRPC traffic for services registered to the Consul catalog that are available at the `api-workload` port are routed according to the following criteria: + +- For traffic with a header that contains a `x-debug` value of exactly `1`, Consul modifies the response and request headers and routes to the `api` service at the `api-workload` port. +- For traffic with a header that contains a `x-debug` value of exactly `2`, Consul modifies the response and request headers and routes to the `api-admin` service at the `admin-workload` port. + +This example also includes how to include filters that modify request or response headers. + +```yaml +apiVersion: mesh.consul.hashicorp.com/v2beta1 +kind: GRPCRoute +metadata: + name: api-match-split + namespace: default +spec: + parentRefs: + - ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api-workload" + rules: + - matches: + - headers: + - type: "HEADER_MATCH_TYPE_EXACT" + name: "x-debug" + value: "1" + filters: + - requestHeaderModifier: + add: + - name: "request-foo" + value: "request-bar" + - responseHeaderModifier: + add: + - name: "response-foo" + value: "response-bar" + backendRefs: + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api-workload" + - matches: + - headers: + - type: "HEADER_MATCH_TYPE_EXACT" + name: "x-debug" + value: "2" + filters: + - requestHeaderModifier: + add: + - name: "request-foo" + value: "request-bar" + - responseHeaderModifier: + add: + - name: "response-foo" + value: "response-bar" + backendRefs: + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api-admin + # The configuration targets the workload port, not the service port. + port: "admin-workload" +``` \ No newline at end of file diff --git a/website/content/docs/k8s/multiport/reference/httproute.mdx b/website/content/docs/k8s/multiport/reference/httproute.mdx new file mode 100644 index 0000000000000..377e5f3a7235f --- /dev/null +++ b/website/content/docs/k8s/multiport/reference/httproute.mdx @@ -0,0 +1,921 @@ +--- +layout: docs +page_title: HTTPRoute resource configuration reference +description: The HTTPRoute resource CRD configures L7 HTTP traffic behavior within the service mesh. HTTPRoute is a GAMMA resource that requires the v2 catalog API. Learn how to configure the HTTPRoute CRD with specifications and example configurations. +--- + +# HTTPRoute resource configuration reference + +This page provides reference information for the `HTTPRoute` resource, which defines behavior for L7 HTTP traffic within the service mesh. + +This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/catalog/v2). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog/v1). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/). + +## Configuration model + +The following list outlines field hierarchy, language-specific data types, and requirements in an HTTP route CRD. Click on a property name to view additional details, including default values. + +- [`apiVersion`](#apiversion): string | required | must be set to `mesh.consul.hashicorp.com/v2beta1` +- [`kind`](#kind): string | required | must be set to `HTTPRoute` +- [`metadata`](#metadata): map | required + - [`name`](#metadata-name): string | required + - [`namespace`](#metadata-namespace): string | optional +- [`spec`](#spec): map | required + - [`parentRefs`](#spec-parentrefs): map | required + - [`port`](#spec-parentrefs-port): string + - [`ref`](#spec-parentrefs-ref): string | required + - [`name`](#spec-parentrefs-ref-name): string + - [`type`](#spec-parentrefs-ref-type): map + - [`group`](#spec-parentrefs-ref-type): string + - [`groupVersion`](#spec-parentrefs-ref-type): string + - [`kind`](#spec-parentrefs-ref-type): string + - [`rules`](#spec-rules): map | required + - [`backendRefs`](#spec-rules-backendrefs): map + - [`backendRef`](#spec-rules-backendrefs-backendref): map + - [`datacenter`](#spec-rules-backendrefs-backendref-datacenter): string + - [`port`](#spec-rules-backendrefs-backendref-port): string + - [`ref`](#spec-rules-backendrefs-backendref-ref): map + - [`name`](#spec-rules-backendrefs-backendref-ref-name): string + - [`type`](#spec-rules-backendrefs-backendref-ref-type): map + - [`group`](#spec-rules-backendrefs-backendref-ref-type): string + - [`groupVersion`](#spec-rules-backendrefs-backendref-ref-type): string + - [`kind`](#spec-rules-backendrefs-backendref-ref-type): string + - [`filters`](#spec-rules-backendrefs-filters): map + - [`requestHeaderModifier`](#spec-rules-backendrefs-filters-requestheadermodifier): map + - [`add`](#spec-rules-backendrefs-filters-requestheadermodifier): map + - [`set`](#spec-rules-backendrefs-filters-requestheadermodifier): map + - [`remove`](#spec-rules-backendrefs-filters-requestheadermodifier): map + - [`responseHeaderModifier`](#spec-rules-backendrefs-filters-responseheadermodifier): map + - [`add`](#spec-rules-backendrefs-filters-responseheadermodifier): map + - [`set`](#spec-rules-backendrefs-filters-responseheadermodifier): map + - [`remove`](#spec-rules-backendrefs-filters-responseheadermodifier): map + - [`urlRewrite`](#spec-rules-backendrefs-filters-urlrewrite): map + - [`pathPrefix`](#spec-rules-backendrefs-filters-urlrewrite): string + - [`weight`](#spec-rules-backendrefs-weight): number | `1` + - [`filters`](#spec-rules-filters): map + - [`requestHeaderModifier`](#spec-rules-filters-requestheadermodifier): map + - [`add`](#spec-rules-filters-requestheadermodifier): map + - [`set`](#spec-rules-filters-requestheadermodifier): map + - [`remove`](#spec-rules-filters-requestheadermodifier): map + - [`responseHeaderModifier`](#spec-rules-filters-responseheadermodifier): map + - [`add`](#spec-rules-filters-responseheadermodifier): map + - [`set`](#spec-rules-filters-responseheadermodifier): map + - [`remove`](#spec-rules-filters-responseheadermodifier): map + - [`urlRewrite`](#spec-rules-filters-urlrewrite): map + - [`pathPrefix`](#spec-rules-filters-urlrewrite): string + - [`matches`](#spec-rules-matches): map + - [`headers`](#spec-rules-matches-headers): map + - [`name`](#spec-rules-matches-headers-name): string + - [`type`](#spec-rules-matches-headers-type): string + - [`value`](#spec-rules-matches-headers-value): string + - [`method`](#spec-rules-matches-method): string + - [`path`](#spec-rules-matches-path): map + - [`type`](#spec-rules-matches-path-type): string + - [`value`](#spec-rules-matches-path-value): string + - [`queryParams`](#spec-rules-matches-queryparams): map + - [`name`](#spec-rules-matches-queryparams-name): string + - [`type`](#spec-rules-matches-queryparams-type): string + - [`value`](#spec-rules-matches-queryparams-value): string + - [`retries`](#spec-rules-retries): map + - [`number`](#spec-rules-retries-number): map + - [`value`](#spec-rules-retries-number): number + - [`onConditions`](#spec-rules-retries-onconditions): map of strings + - [`onConnectFailure`](#spec-rules-retries-onconnectfailure): boolean | `false` + - [`onStatusCodes`](#spec-rules-retries-onconditions): map of integers + - [`timeouts`](#spec-rules-timeouts): map + - [`idle`](#spec-rules-timeouts-idle): string + - [`request`](#spec-rules-timeouts-request): string + +## Complete configuration + +When every field is defined, an HTTP route CRD has the following form: + +```yaml +apiVersion: mesh.consul.hashicorp.com/v2beta1 # required +kind: HTTPRoute # required +metadata: + name: + namespace: +spec: + parentRefs: + port: + - ref: + name: + type: + group: + groupVersion: + kind: + rules: + - backendRefs: + - backendRef: + datacenter: + port: + ref: + name: + type: + group: + groupVersion: + kind: + filters: + - requestHeaderModifier: + add: + name: + value: + - responseHeaderModifier: + set: + name: + value: + urlRewrite: + pathPrefix: + weight: 1 + filters: + requestHeaderModifier: + remove: + name: + value: + responseHeaderModifier: + add: + name: + value: + urlRewrite: + pathPrefix: + matches: + headers: + name: + type: + value: + method: + path: + type: + value: / + queryParams: + name: + type: + value: + retries: + number: + value: 1 + onConditions: ["cancelled", "unavailable"] + onConnectFailure: false + onStatusCodes: [400, 404] + timeouts: + idle: <1s> + request: <1s> +``` + +## Specification + +This section provides details about the fields you can configure in the `HTTPRoute` custom resource definition (CRD). + +### `apiVersion` + +Specifies the version of the Consul API for integrating with Kubernetes. The value must be `mesh.consul.hashicorp.com/v2beta1`. + +#### Values + +- Default: None +- This field is required. +- String value that must be set to `mesh.consul.hashicorp.com/v2beta1`. + +### `kind` + +Specifies the type of CRD to implement. Must be set to `HTTPRoute`. + +#### Values + +- Default: None +- This field is required. +- Data type: String value that must be set to `HTTPRoute`. + +### `metadata` + +Map that contains an arbitrary name for the CRD and the namespace it applies to. + +#### Values + +- Default: None +- Data type: Map + +### `metadata.name` + +Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information. + +#### Values + +- Default: None +- This field is required. +- Data type: String + +### `metadata.namespace` + +Specifies the namespace that the service resolver applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information. + +#### Values + +- Default: None +- Data type: String + +### `spec` + +Map that contains the details about the `HTTPRoute` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children. + +When using this CRD, the `spec` field closely resembles the `HTTPRoute` GAMMA resource. Refer to [HTTPRoute in the Kubernetes documentation](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.HTTPRoute). + +#### Values + +- Default: None +- This field is required. +- Data type: Map + +### `spec.parentRefs` + +Specifies the services and other resources to attach the route to. You can only define one `parentsRefs` configuration for each route. To attach the route to multiple resources, specify additional [`spec.parentRefs.ref`](#spec-parentrefs-ref) configurations in the `parentsRefs` block. You can only specify the name of one port for the route. Any resources that send traffic through the route use the same port. + +#### Values + +- Default: None +- This field is required. +- Data type: Map + +### `spec.parentRefs.port` + +Specifies the name of the port that the configuration applies to. + +#### Values + +- Default: None +- Data type: String + +### `spec.parentRefs.ref` + +Specifies the resource that the route attaches to. + +#### Values + +- Default: None +- Data type: Map + +### `spec.parentRefs.ref.name` + +Specifies the user-defined name of the resource that the configuration applies to. + +#### Values + +- Default: None +- Data type: String + +### `spec.parentRefs.ref.type` + +Specifies the type of resource that the configuration applies to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`. + +#### Values + +- Default: None +- Data type: Map containing the following parameters: + + | Parameter | Description | Data type | Default | + | :------------ | :------------------------------------------------------------------- | :-------- | :------- | + | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `kind` | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | + +### `spec.rules` + +Specifies rules for sidecar proxies to direct a service's HTTP traffic within the service mesh, including filtering, retry, and timeout behavior. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs` + +Specifies the Kubernetes Service backend to direct HTTP traffic to when a request matches the service described in [`spec.parentRefs`](#spec-parentrefs). The Service backend is the collection of endpoint IPs for the service. Refer to [the Kubernetes Gateway API specification](https://gateway-api.sigs.k8s.io/concepts/gamma/#an-overview-of-the-gateway-api-for-service-mesh) for more information about Service backends. + +When a valid Service backend cannot be reached and no additional filters apply, traffic that matches the rule returns a 500 status code. + +When different Service backends are specified in [`spec.rules.backendRefs.weight`](#spec-rules-backendrefs-weight) and one of the backends is invalid, Consul continues to apply the specified weights instead of adjusting the relative weights to exclude traffic to the invalid backend. For example, when traffic is configured in a 50-50 split between `api` and `admin` and no valid endpoints for `admin` can be reached, the 50% of traffic intended for `admin` returns with a 500 status code. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs.backendRef` + +Specifies an individual Service backend where matching requests should be sent. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs.backendRef.datacenter` + +Specifies the name of the Consul datacenter that registered the Service backend that the configuration routes traffic to. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.backendRefs.backendRef.port` + +Specifies the name of the port for the Consul service that the configuration routes traffic to. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.backendRefs.backendRef.ref` + +The Consul service that the configuration routes traffic to. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs.backendRef.ref.name` + +Specifies the user-defined name of the resource that the configuration routes traffic to. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.backendRefs.backendRef.ref.type` + +Specifies the type of resource that the configuration routes traffic to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`. + +#### Values + +- Default: None +- Data type: Map containing the following parameters: + + | Parameter | Description | Data type | Default | + | `group` | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String | None | + | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None | + | `kind` | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`. | String | None | + +### `spec.rules.backendRefs.filters` + +Specifies filtering behavior for services configured in the same [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.backendRefs.filters.requestHeaderModifier` + +Specifies a set of header modification rules applied to requests routed with the HTTPRoute resource. + +#### Values + +- Default: None +- Values: Object containing one or more fields that define header modification rules: + - `add`: Map of one or more key-value pairs. + - `set`: Map of one or more key-value pairs. + - `remove`: Map of one or more key-value pairs. + +The following table describes how to configure values for request headers: + +| Rule | Description | Type | +| --- | --- | --- | +| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | +| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | +| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | + +##### Use variable placeholders + +For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. + +### `spec.rules.backendRefs.filters.responseHeaderModifier` + +Specifies a set of header modification rules applied to responses routed with the HTTPRoute resource. + +#### Values + +- Default: None +- Values: Object containing one or more fields that define header modification rules: + - `add`: Map of one or more key-value pairs. + - `set`: Map of one or more key-value pairs. + - `remove`: Map of one or more key-value pairs. + +The following table describes how to configure values for request headers: + +| Rule | Description | Type | +| --- | --- | --- | +| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | +| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | +| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | + +##### Use variable placeholders + +For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. + +### `spec.rules.backendRefs.filters.urlRewrite` + +Specifies a path to modify the URL with when a request is forwarded. + +#### Values + +- Default: None +- Data type: Map containing the following parameter: + + | Parameter | Description | Data type | Default | + | :------------ | :------------------------------------------------------------------------------------------------- | --------- | ------- | + | `pathPrefix` | Specifies the path that is prepended to the URL. | String | None | + +### `spec.rules.backendRefs.weight` + +Specifies the proportion of requests routed to the specified service. + +This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. + +When this parameter is not specified, Consul defaults to `1`. + +#### Values + +- Default: `1` +- Data type: Integer + +### `spec.rules.filters` + +Specifies filtering behavior for all requests that match the service defined in [`spec.parentRefs`](#spec-parent-refs). + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.filters.requestHeaderModifier` + +Specifies a set of header modification rules applied to requests that match the service defined in [`spec.parentRefs`](#spec-parent-refs). + +#### Values + +- Default: None +- Values: Object containing one or more fields that define header modification rules: + - `add`: Map of one or more key-value pairs. + - `set`: Map of one or more key-value pairs. + - `remove`: Map of one or more key-value pairs. + +The following table describes how to configure values for request headers: + +| Rule | Description | Type | +| --- | --- | --- | +| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | +| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | +| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | + +##### Use variable placeholders + +For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. + +### `spec.rules.filters.responseHeaderModifier` + +Specifies a set of header modification rules applied to responses from services matching [`spec.parentRefs`](#spec-parent-refs). + +#### Values + +- Default: None +- Values: Object containing one or more fields that define header modification rules: + - `add`: Map of one or more key-value pairs. + - `set`: Map of one or more key-value pairs. + - `remove`: Map of one or more key-value pairs. + +The following table describes how to configure values for request headers: + +| Rule | Description | Type | +| --- | --- | --- | +| `add` | Defines a set of key-value pairs to add to the header. Use header names as the keys. Header names are not case-sensitive. If header values with the same name already exist, the value is appended and Consul applies both headers. You can [use variable placeholders](#use-variable-placeholders). | map of strings | +| `set` | Defines a set of key-value pairs to add to the request header or to replace existing header values with. Use header names as the keys. Header names are not case-sensitive. If header values with the same names already exist, Consul replaces the header values. You can [use variable placeholders](#use-variable-placeholders). | map of strings | +| `remove` | Defines a list of headers to remove. Consul removes only headers containing exact matches. Header names are not case-sensitive. | list of strings | + +##### Use variable placeholders + +For `add` and `set`, if the service is configured to use Envoy as the proxy, the value may contain variables to interpolate dynamic metadata into the value. For example, using the variable `%DOWNSTREAM_REMOTE_ADDRESS%` allows you to pass a value that is generated when the split occurs. + +### `spec.rules.filters.urlRewrite` + +Specifies a path to modify the URL with when a request matching [`spec.parentRefs`](#spec-parent-refs) is forwarded. + +#### Values + +- Default: None +- Data type: Map containing the following parameter: + + | Parameter | Description | Data type | Default | + | :------------ | :------------------------------------------------------------------------------------------------- | --------- | ------- | + | `pathPrefix` | Specifies a path to prepend to the URL when a request matching [`spec.parentRefs`](#spec-parent-refs) is forwarded. | String | None | + +### `spec.rules.matches` + +Specifies rules for matching traffic to services described in [`spec.parentRefs`](#spec-parent-refs) according to the request header or method. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.matches.headers` + +Specifies criteria for matching HTTP request headers. + +When [`spec.rules.matches.headers.value`] is specified multiple times, a request must match all of the specified values for the route to be selected. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.matches.headers.name` + +Specifies the name of a HTTP request header to match on. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.matches.headers.type` + +Specifies a type of match to perform on the HTTP request header. Supported match types include: unspecified, exact, regex, present, prefix, and suffix. + +#### Values + +- Default: None +- Data type: String that should match one of the following values: + + - `HEADER_MATCH_TYPE_UNSPECIFIED` + - `HEADER_MATCH_TYPE_EXACT` + - `HEADER_MATCH_TYPE_REGEX` + - `HEADER_MATCH_TYPE_PRESENT` + - `HEADER_MATCH_TYPE_PREFIX` + - `HEADER_MATCH_TYPE_SUFFIX` + +### `spec.rules.matches.headers.value` + +Specifies the value of the HTTP request header to match. When this field is specified multiple times, a request must match all of the specified values for the route to be selected. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.matches.method` + +Specifies the value of the HTTP method to match. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.matches.path` + +Specifies an HTTP request path to match. When this field is not specified, the CRD matches on the `/` path by default. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.matches.path.type` + +Specifies a type of match to perform on the HTTP path. Supported match types include: unspecified, exact, prefix, and regex. + +#### Values + +- Default: None +- Data type: String that should match one of the following values: + +- `PATH_MATCH_TYPE_UNSPECIFIED` +- `PATH_MATCH_TYPE_EXACT` +- `PATH_MATCH_TYPE_PREFIX` +- `PATH_MATCH_TYPE_REGEX` + +### `spec.rules.matches.path.value` + +Value of the HTTP path to match on. + +#### Values + +- Default: `/` +- Data type: String + +### `spec.rules.matches.queryParams` + +Specifies HTTP query parameters to match on. When [`spec.rules.matches.queryParams.value`] is specified multiple times, a request must match all of the specified values for the route to be selected. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.matches.queryParams.name` + +Specifies the name of the HTTP query parameter to match. Query parameters matches require exact matches between strings. + +If multiple entries specify identical query parameter names, only the first entry with an equivalent name matches. Subsequent entries with an equivalent query parameter name are ignored. If an HTTP request repeats a query parameter, the behavior is intentionally undefined because different data planes have different capabilities. However, we recommend that matching against the first value of the parameter if the data plane supports it, as this behavior is expected in other load balancing contexts. + +Do not route traffic based on repeated query parameters, as differences in data plane implementations may produce errors. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.matches.queryParams.type` + +Specifies a type of match to perform on the HTTP request header. Supported match types include: unspecified, exact, regex, and present. + +#### Values + +- Default: None +- Data type: String that should match one of the following values: + + - `HEADER_MATCH_TYPE_UNSPECIFIED` + - `HEADER_MATCH_TYPE_EXACT` + - `HEADER_MATCH_TYPE_REGEX` + - `HEADER_MATCH_TYPE_PRESENT` + +### `spec.rules.matches.queryParams.value` + +Specifies the value of the HTTP query parameter to match. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.retries` + +Specifies retry logic for routing HTTP traffic. + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.retries.number` + +Specifies the number of retries to attempt when a request fails. + +#### Values + +- Default: None +- Data type: Map that contains the following parameter: + + | Parameter | Description | Data type | Default | + | :-------- | :------------------------------------------- | --------- | ------- | + | `value` | Specifies the number of retries to attempt. | Integer | None | + +### `spec.rules.retries.onConditions` + +Specifies Envoy conditions that cause an automatic retry attempt. + +#### Values + +- Default: None +- Data type: Map of strings + +### `spec.rules.retries.onConnnectFailure` + +Enables an automatic retry attempt when a connection failure error occurs. + +#### Values + +- Default: `false` +- Data type: Boolean + +### `spec.rules.retries.onStatusCodes` + +Specifies the response status codes that are eligible for retry attempts. + +#### Values + +- Default: None +- Data type: Map of integers + +### `spec.rules.timeouts` + +Specifies timeout logic when routing HTTP traffic + +#### Values + +- Default: None +- Data type: Map + +### `spec.rules.timeouts.idle` + +Specifies the total amount of time permitted for the request stream to be idle before a timeout occurs. + +This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`. + +#### Values + +- Default: None +- Data type: String + +### `spec.rules.timeouts.request` + +Specifies the total amount of time spent processing the entire downstream request, including retries, before triggering a timeout. + +This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`. + +#### Values + +- Default: None +- Data type: String + +## Examples + +The following examples demonstrate common HTTP route CRD configuration patterns for specific use cases. + +### Split HTTP traffic between two ports + +The following example splits traffic for the `api` service. HTTP traffic for services registered to the Consul catalog that are available at the `api` port is split so that 50% of the traffic routes to the service at the `api` port and 50% routes to the service at the `admin` port. + +```yaml +apiVersion: mesh.consul.hashicorp.com/v2beta1 +kind: HTTPRoute +metadata: + name: api-split + namespace: default +spec: + parentRefs: + - ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api" + rules: + - backendRefs: + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api" + weight: 50 + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "admin" + weight: 50 +``` + +### Route traffic by matching header + +The following examples routes HTTP traffic for the `api` service according to its header HTTP traffic for services registered to the Consul catalog that are available at the `api-workload` port are routed according to the following criteria: + +- For traffic with a header that contains a `x-debug` value of exactly `1`, Consul routes to the `api` service at the `api-workload` port. +- For traffic with a header that contains a `x-debug` value of exactly `2`, Consul routes to the `api-admin` service at the `admin-workload` port. + +This example also configures Consul to modify request and response headers when routing traffic. + +```yaml +apiVersion: mesh.consul.hashicorp.com/v2beta1 +kind: HTTPRoute +metadata: + name: api-filter + namespace: default +spec: + parentRefs: + - ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api-workload" + rules: + - matches: + - headers: + - type: "HEADER_MATCH_TYPE_EXACT" + name: "x-debug" + value: "1" + filters: + - requestHeaderModifier: + add: + - name: "request-foo" + value: "request-bar" + - responseHeaderModifier: + add: + - name: "response-foo" + value: "response-bar" + backendRefs: + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api-workload" + - matches: + - headers: + - type: "HEADER_MATCH_TYPE_EXACT" + name: "x-debug" + value: "2" + filters: + - requestHeaderModifier: + add: + - name: "request-foo" + value: "request-bar" + - responseHeaderModifier: + add: + - name: "response-foo" + value: "response-bar" + backendRefs: + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api-admin + # The configuration targets the workload port, not the service port. + port: "admin-workload" +``` + +### Route traffic by matching header and query parameter + +The following examples routes HTTP traffic for the `api` service according to its header HTTP traffic for services registered to the Consul catalog that are available at the `api-workload` port are routed according to the following criteria: + +- For traffic with a header _and_ a query parameter that both contain `x-debug` values of exactly `1`, Consul routes to the `api` service at the `api-workload` port. +- For traffic with a header _and_ a query parameter that both contain `x-debug` values of exactly `2`, Consul routes to the `api-admin` service at the `admin-workload` port. + +```yaml +apiVersion: mesh.consul.hashicorp.com/v2beta1 +kind: HTTPRoute +metadata: + name: api-match-split + namespace: default +spec: + parentRefs: + - ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api-workload" + rules: + - matches: + - headers: + - type: "HEADER_MATCH_TYPE_EXACT" + name: "x-debug" + value: "1" + queryParams: + - type: "QUERY_PARAM_MATCH_TYPE_EXACT" + name: "x-debug" + value: "1" + backendRefs: + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api + # The configuration targets the workload port, not the service port. + port: "api-workload" + - matches: + - headers: + - type: "HEADER_MATCH_TYPE_EXACT" + name: "x-debug" + value: "2" + queryParams: + - type: "QUERY_PARAM_MATCH_TYPE_EXACT" + name: "x-debug" + value: "2" + backendRefs: + - backendRef: + ref: + type: + group: catalog + groupVersion: v2beta1 + kind: Service + name: api-admin + # The configuration targets the workload port, not the service port. + port: "admin-workload" +``` \ No newline at end of file diff --git a/website/content/docs/k8s/multiport/reference/proxyconfiguration.mdx b/website/content/docs/k8s/multiport/reference/proxyconfiguration.mdx new file mode 100644 index 0000000000000..735a1f905b8a9 --- /dev/null +++ b/website/content/docs/k8s/multiport/reference/proxyconfiguration.mdx @@ -0,0 +1,691 @@ +--- +layout: docs +page_title: ProxyConfiguration resource configuration reference +description: The ProxyConfiguration resource CRD configures sidecar proxy behavior within the service mesh. Learn how to configure bootstrap and dynamic configurations for proxies according to Workload characteristics with specifications and example configurations. +--- + +# ProxyConfiguration resource configuration reference + +This page provides reference information for the `ProxyConfigurations` resource, which defines proxy behavior for traffic within the service mesh. The resource specifies both bootstrap and dynamic configurations for proxies. + +This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/catalog/v2). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog/v1). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/). + +## Configuration model + +The following list outlines field hierarchy, language-specific data types, and requirements in a ProxyConfiguration CRD. Click on a property name to view additional details, including default values. + +- [`apiVersion`](#apiversion): string | required | must be set to `mesh.consul.hashicorp.com/v2beta1` +- [`kind`](#kind): string | required | must be set to `ProxyConfiguration` +- [`metadata`](#metadata): map | required + - [`name`](#metadata-name): string | required + - [`namespace`](#metadata-namespace): string | optional +- [`spec`](#spec): map | required + - [`workloads`](#spec-workloads): map + - [`filter`](#spec-workloads): string + - [`names`](#spec-workloads): array of strings + - [`prefixes`](#spec-workloads): array of strings + - [`bootstrapConfig`](#spec-bootstrapconfig): map + - [`dogstatsdUrl`](#spec-bootstrapconfig): string + - [`overrideJsonTpl`](#spec-bootstrapconfig): string + - [`prometheusBindAddr`](#spec-bootstrapconfig): string + - [`readyBindAddr`](#spec-bootstrapconfig): string + - [`staticClustersJson`](#spec-bootstrapconfig): string + - [`staticListenersJson`](#spec-bootstrapconfig): string + - [`statsBindAddr`](#spec-bootstrapconfig): string + - [`statsConfigJson`](#spec-bootstrapconfig): string + - [`statsFlushInterval`](#spec-bootstrapconfig): string + - [`statsSinksJson`](#spec-bootstrapconfig): string + - [`statsTags`](#spec-bootstrapconfig): array of strings + - [`statsdUrl`](#spec-bootstrapconfig): string + - [`telemetryCollectorBindSocketDir`](#spec-bootstrapconfig): string + - [`tracingConfigJson`](#spec-bootstrapconfig): string + - [`dynamicConfig`](#spec-dynamicconfig): map + - [`accessLogs`](#spec-dynamicconfig-accesslogs): map + - [`enabled`](#spec-dynamicconfig-accesslogs-enabled): boolean | `false` + - [`disableListenerLogs`](#spec-dynamicconfig-accesslogs-disablelistenerlogs): boolean | `false` + - [`jsonFormat`](#spec-dynamicconfig-accesslogs-jsonformat): string + - [`path`](#spec-dynamicconfig-accesslogs-path): string + - [`textFormat`](#spec-dynamicconfig-accesslogs-textformat): string + - [`type`](#spec-dynamicconfig-accesslogs-type): string + - [`exposeConfig`](#spec-dynamicconfig-exposeconfig): map + - [`exposePaths`](#spec-dynamicconfig-exposeconfig-exposepaths): map + - [`listenerPort`](#spec-dynamicconfig-exposeconfig-exposepaths-listenerport): integer + - [`localPathPort`](#spec-dynamicconfig-exposeconfig-exposepaths-localpathport): integer + - [`path`](#spec-dynamicconfig-exposeconfig-exposepaths-path): string + - [`protocol`](#spec-dynamicconfig-exposeconfig-exposepaths-protocol): string + - [`inboundConnections`](#spec-dynamicconfig-inboundconnections): map + - [`balanceInboundConnections`](#spec-dynamicconfig-inboundconnections-balanceinboundconnections): string + - [`maxInboundConnections`](#spec-dynamicconfig-exposeconfig-inboundconnections-maxinboundconnections): integer + - [`listenerTracingJson`](#spec-dynamicconfig-listenertracingjson): string + - [`localClusterJson`](#spec-dynamicconfig-localclusterjson): string + - [`localConnection`](#spec-dynamicconfig-localconnection): map + - [`connectTimeout`](#spec-dynamicconfig-localconnection-connecttimeout): string + - [`requestTimeout`](#spec-dynamicconfig-localconnection-requesttimeout): string + - [`meshGatewayMode`](#spec-dynamicconfig-meshgatewaymode): string + - [`mode`](#spec-dynamicconfig-mode): string + - [`publicListenerJson`](#spec-dynamicconfig-publiclistenerjson): string + - [`transparentProxy`](#spec-dynamicconfig-transparentproxy): map + - [`dialedDirectly`](#spec-dynamicconfig-transparentproxy-dialeddirectly): boolean | `false` + - [`outboundListenerPort`](#spec-dynamicconfig-transparentproxy-outboundlistenerport): integer | `15001` + +## Complete configuration + +When every field is defined, an ProxyConfigurations CRD has the following form: + +```yaml +apiVersion: mesh.consul.hashicorp.com/v2beta1 # required +kind: ProxyConfiguration # required +metadata: + name: + namespace: +spec: + workloads: # required + filter: "Service.Meta.version == v1" + names: ["api", "admin"] + prefixes: ["
", ""]
+  bootstrapConfig: 
+    dogstatsdUrl: 
+    overrideJsonTpl: 
+    prometheusBindAddr: <0.0.0.0>
+    readyBindAddr: 
+    staticClustersJson: 
+    staticListenersJson: 
+    statsBindAddr: <0.0.0.0>
+    statsConfigJson: 
+    statsFlushInterval: 5000ms
+    statsSinkJson: 
+    statsTags:
+      - 
+    statsdUrl: 
+    telemetryCollectorBindSocketDir: 
+    tracingConfigJson: 
+  dynamicConfig:
+    accessLogs:
+      enabled: false
+      disableListenerLogs: false
+      jsonFormat: 
+      path: 
+      textFormat: 
+      type: 
+    exposeConfig:
+      exposePaths:
+        listenerPort: 42
+        localPathPort: 4242
+        path: 
+        protocol: 
+      inboundConnections:
+        balanceInboundConnections: 
+        maxInboundConnections: 1024
+    listenerTracingJson: 
+    localClusterJson: 
+    localConnection:
+      connectTimeout: <1s>
+      requestTimeout: <1s>
+    meshGatewayMode: 
+    mode: 
+    publicListenerJson: 
+    transparentProxy:
+      dialedDirectly: false
+      outboundListenerPort: 15001
+```
+
+## Specification
+
+This section provides details about the fields you can configure in the `ProxyConfiguration` custom resource definition (CRD).
+
+### `apiVersion`
+
+Specifies the version of the Consul API for integrating with Kubernetes. The value must be `mesh.consul.hashicorp.com/v2beta1`.
+
+#### Values
+
+- Default: None
+- This field is required.
+- String value that must be set to `mesh.consul.hashicorp.com/v2beta1`.
+
+### `kind`
+
+Specifies the type of CRD to implement. Must be set to `ProxyConfiguration`.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: String value that must be set to `ProxyConfiguration`.
+
+### `metadata`
+
+Map that contains an arbitrary name for the CRD and the namespace it applies to.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `metadata.name`
+
+Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: String
+
+### `metadata.namespace` 
+
+Specifies the namespace that the proxy configuration applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec`
+
+Map that contains the details about the `ProxyConfiguration` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: Map
+
+### `spec.workloads`
+
+Specifies the workloads that the proxy configuration applies to. You can select workloads by name, prefix, or by using a filter expression.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: Map that can contain the following parameters:
+
+ | Parameter     | Description                                                                                                                                                                                                                                                                                   | Data type | Default |
+    | :------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------- |
+    | `filter`      | Specifies an expression that filters workloads.  For more information about creating and using expressions to filter, refer to [filtering](/consul/api-docs/features/filtering).   | String    | None    |
+    | `names` | Specifies one or more names of workloads the proxy configuration applies to. | Array of strings | None |
+    | `prefixes` | Specifies one or more prefixes. Proxy configurations apply to workloads with one of the prefixes. | Array of strings | None |
+
+### `spec.bootstrapConfig`
+
+Specifies initial bootstrap settings for the Envoy proxy, as well as proxy configuration settings that require the proxy to restart when applied. For more information, refer to [Envoy proxy bootstrap configuration](/consul/docs/connect/proxies/envoy#bootstrap-configuration).
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.bootstrapConfig.dogstatsdUrl`
+
+Specifies a URL that identifies a DataDog DogStatsD listener. Envoy sends metrics to this listener.
+
+Format the URL as `udp://ip:port` or `unix://uds/path`. For example, `udp://127.0.0.1:8125` configures a local UDP DogStatsD listener for every host. TCP is not supported.
+
+The UDP URL must use an IP address. DNS names are not supported.
+
+For more information about configuring a UNIX domain socket with DogStatsD, refer to [the DataDog documentation](https://docs.datadoghq.com/developers/dogstatsd/unix_socket?tab=kubernetes#setup).
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.overrideJsonTpl`
+
+
+This field offers complete control of the proxy's bootstrap. Be aware that major deviations from the default template may break Consul's ability to correctly manage the proxy or enforce its security model.
+
+
+Specifies a template in Go template syntax to use in place of [the default template](https://github.com/hashicorp/consul/blob/71d45a34601423abdfc0a64d44c6a55cf88fa2fc/command/connect/envoy/bootstrap_tpl.go#L129) when generating the bootstrap configuration using the [`consul connect envoy` command](/consul/commands/connect/envoy). For information about the variables Consul can interpolate in the template, refer to the [documentation in `bootstrap_tpl.go`](https://github.com/hashicorp/consul/blob/71d45a34601423abdfc0a64d44c6a55cf88fa2fc/command/connect/envoy/bootstrap_tpl.go#L5).
+
+Refer to [Envoy proxy escape-hatch overrides](/consul/docs/connect/proxies/envoy#escape-hatch-overrides) for more information.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.prometheusBindAddr`
+
+Configures the proxy to expose a Prometheus metrics endpoint to the public network. Format the endpoint as `ip:port`. The port and IP and port combination must be free within the network namespace where the proxy runs. The IP `0.0.0.0` binds to all available interfaces or a pod IP address if supported by your existing network settings.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.readyBindAddr`
+
+Specifies the location to configure the proxy's readiness probe. Format as `ip:port`. 
+
+ By default, the proxy does not have a readiness probe configured on it.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.staticClustersJson`
+
+Specifies one or more [Envoy clusters](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/cluster/v3/cluster.proto) to append to the array of [static clusters](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-staticresources-clusters) in the bootstrap configuration.
+
+This field enables you to add custom clusters, such as tracing sinks, to the bootstrap configuration. In order to configure a single cluster, specify a single JSON object with the cluster details.
+
+Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.staticListenersJson`
+
+Specifies one or more [Envoy listeners](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/listener/v3/listener.proto) to append to the array of [static listeners](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-staticresources-listeners) definitions.
+
+You can use this field to set up limited access that bypasses the service mesh's mTLS or authorization for health checks or metrics.
+
+Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.statsBindAddr`
+
+Specifies that the proxy should expose the `/stats` prefix to the _public_ network at the `ip:port` provided. The IP and port combination must be free within the network namespace where the proxy runs. The IP `0.0.0.0` binds to all available interfaces or a pod IP address if supported by your existing network settings.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.statsConfigJson`
+
+Specifies a complete [stats config](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-stats-config).
+
+When provided, this field overrides [`spec.bootstrapConfig.statsTags`](#spec-bootstrapconfig-statstags) and enables full control over dynamic tag replacements.
+
+Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.statsFlushInterval`
+
+ Configures Envoy's [`stats_flush_interval`](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-stats-flush-interval), which measures the length of the interval between stats sink flushes.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.statsSinkJson`
+
+Specifies one or more [stats sinks](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-stats-sinks) to append to sinks defined using [`spec.bootstrapConfig.statsdUrl`](#spec-bootstrapconfig-statsdurl) or [`spec.bootstrapConfig.dogstatsdUrl`](#spec-bootstrapconfig-dogstatsdurl).
+
+Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.statsTags`
+
+Specifies one or more static tags to add to all metrics produced by the proxy.
+
+#### Values
+
+- Default: None
+- Data type: Array of strings
+
+### `spec.bootstrapConfig.statsdUrl`
+
+Specifies a URL that identifies a StatsD listener. Envoy sends metrics to this listener.
+
+Format the URL as `udp://ip:port`. For example, `udp://127.0.0.1:8125` configures a local StatsD listener for every host. TCP is not supported.
+
+The URL must use an IP address. DNS names are not supported.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.telemetryCollectorBindSocketDir`
+
+Specifies the directory of the Unix socket Envoy sends metrics to so that the Consul telemetry collector can collect them.
+
+The socket is not configured by default.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.bootstrapConfig.tracingConfigJson`
+
+Specifies a configuration for an external tracing provider as described in [the Envoy documentation](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/bootstrap/v3/bootstrap.proto#envoy-v3-api-field-config-bootstrap-v3-bootstrap-tracing). Most tracing providers also require adding static clusters to define the endpoints to send tracing data to.
+
+Refer to [Envoy proxy advanced bootstrap options](/consul/docs/connect/proxies/envoy#advanced-bootstrap-options) for more information and examples.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig`
+
+Specifies configuration settings for the Envoy proxy that are applied without restarting the proxy. For more information, refer to [Envoy proxy dynamic configuration](/consul/docs/connect/proxies/envoy#dynamic-configuration).
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.dynamicConfig.accessLogs`
+
+Specifies the format and output for the proxy's access logs.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.dynamicConfig.accessLogs.enabled`
+
+When set to `true`, this parameter enables access logs for the proxy.
+
+#### Values
+
+- Default: `false`
+- Data type: Boolean
+
+### `spec.dynamicConfig.accessLogs.usableListenerLogs`
+
+When set to `true`, this parameter disables listener logs for connections that the proxy rejected because they did not have a matching listener filter.
+
+#### Values
+
+- Default: `false`
+- Data type: Boolean
+
+### `spec.dynamicConfig.accessLogs.jsonFormat`
+
+Specifies a JSON format dictionary for the access logs. Refer to [format dictionaries in the Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#format-dictionaries) for more information.
+
+When this field is specified, you cannot also specify [`spec.dynamicConfig.accessLogs.textFormat`](#spec-dynamicconfig-accesslogs-textformat) in the same configuration.
+
+### `spec.dynamicConfig.accessLogs.path`
+
+Specifies a file output path for the access logs.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig.accessLogs.textFormat`
+
+Specifies a format string for the access logs. Refer to [default format string in the Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/configuration/observability/access_log/usage#default-format-string) for more information.
+
+When this field is specified, you cannot also specify [`spec.dynamicConfig.accessLogs.jsonFormat`](#spec-dynamicconfig-accesslogs-jsonformat) in the same configuration.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig.accessLogs.type`
+
+Specifies the output type for the access logs.
+
+#### Values
+
+- Default: None
+- Data type: String containing one of the following values:
+
+  - `LOG_SINK_TYPE_DEFAULT`
+  - `LOG_SINK_TYPE_FILE`
+  - `LOG_SINK_TYPE_STDERR`
+  - `LOG_SINK_TYPE_STDOUT`
+
+### `spec.dynamicConfig.exposeConfig`
+
+Specifies configurations for exposing the proxy.
+
+Refer to [expose paths configuration reference](/consul/docs/connect/proxies/proxy-config-reference#expose-paths-configuration-reference) for more information.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.dynamicConfig.exposeConfig.exposePaths`
+
+Specifies a configuration for exposing an HTTP path through the proxy.
+
+Refer to [expose paths configuration reference](/consul/docs/connect/proxies/proxy-config-reference#expose-paths-configuration-reference) for more information.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.dynamicConfig.exposeConfig.exposePaths.listenerPort`
+
+Specifies the port where the proxy listens for connections. This port must be available for the listener to be set up. If the port is not free, Envoy does not expose a listener for the path but the proxy registration does not fail.
+
+#### Values
+
+- Default: None
+- Data type: Integer
+
+### `spec.dynamicConfig.exposeConfig.exposePaths.localPathPort`
+
+Specifies the port where the local service is listening for connections to the path.
+
+#### Values
+
+- Default: None
+- Data type: Integer
+
+### `spec.dynamicConfig.exposeConfig.exposePaths.path`
+
+The HTTP path to expose. Prefix the path with a slash. For example, `/metrics`.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig.exposeConfig.exposePaths.protocol`
+
+Specifies the protocol of the listener, either HTTP or HTTP/2. For gRPC, use HTTP/2.
+
+#### Values
+
+- Default: None
+- Data type: String containing one of the following values:
+
+  - `EXPOSE_PATH_PROTOCOL_HTTP`
+  - `EXPOSE_PATH_PROTOCOL_HTTP2`
+
+### `spec.dynamicConfig.inboundConnections`
+
+Specifies configurations for how the proxy handles inbound connections.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.dynamicConfig.inboundConnections.balanceInboundConnections`
+
+Specifies the strategy for balancing inbound connections across Envoy worker threads. Consul's service mesh Envoy integration supports the following values:
+
+| Value | Description |
+| :---- | :---------- |
+| Empty string | Inbound connections are not balanced. |
+| `exact_balance` | Balances inbound connections with [Envoy's Exact Balance Strategy](https://cloudnative.to/envoy/api-v3/config/listener/v3/listener.proto.html#config-listener-v3-listener-connectionbalanceconfig-exactbalance). |
+
+#### Values
+
+- Default: `""`
+- Data type: String
+
+### `spec.dynamicConfig.inboundConnections.maxInboundConnections`
+
+Specifies the maximum number of concurrent inbound connections to the local application instance. If not specified, inherits the Envoy default of `1024`.
+
+#### Values
+
+- Default: `1024`
+- Data type: Integer
+
+### `spec.dynamicConfig.listenerTracingJson`
+
+Specifies a tracing configuration to be inserted in the proxy's public and upstreams listeners. Refer to [the Envoy documentation](https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#envoy-v3-api-msg-extensions-filters-network-http-connection-manager-v3-httpconnectionmanager-tracing) for more information.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig.localClusterJson`
+
+Specifies a complete Envoy cluster to be delivered in place of the local application cluster. Use this field to customize timeouts, rate limits, and load balancing strategy.
+
+Refer to [cluster configuration in the Envoy documentation](https://www.envoyproxy.io/docs/envoy/v1.17.2/api-v3/config/cluster/v3/cluster.proto) for more information.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig.localConnection`
+
+Specifies timeout settings for the proxy's connection to the local application. Apply settings separately for each port.
+
+Specify this field as a map containing a key/value. The map keys correspond to port names on the workload. The value contains this parameter's sub-fields.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.dynamicConfig.localConnection.connectTimeout`
+
+Specifies the length of time the proxy is allowed to attempt connections to the local application instance before timing out.
+
+This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig.localConnection.requestTimeout`
+
+Specifies the length of time the proxy is allowed to attempt HTTP requests to the local application instance. Applies to HTTP-based protocols only.
+
+This field accepts a string indicating the number of seconds. For example, indicate five seconds with `5s` and five milliseconds with `0.005s`.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig.meshGatewayMode`
+
+Specifies the proxy's mode of operation for resolving upstreams in remote datacenter destinations. Refer to [Mesh gateway configuration reference](/consul/docs/connect/proxies/proxy-config-reference#mesh-gateway-configuration-reference) for more information.
+
+#### Values
+
+- Default: None
+- Data type: String containing one of the following values:
+
+  - `MESH_GATEWAY_MODE_UNSPECIFIED`
+  - `MESH_GATEWAY_MODE_NONE`
+  - `MESH_GATEWAY_MODE_LOCAL`
+  - `MESH_GATEWAY_MODE_REMOTE`
+
+### `spec.dynamicConfig.mode`
+
+Configures the proxy to operate in transparent, direct, or default mode. Refer to [proxy modes](/consul/docs/connect/proxies/proxy-config-reference#proxy-modes) for more information.
+
+#### Values
+
+- Default: None
+- Data type: String containing one of the following values:
+
+  - `PROXY_MODE_DEFAULT`
+  - `PROXY_MODE_TRANSPARENT`
+  - `PROXY_MODE_DIRECT`
+
+### `spec.dynamicConfig.publicListenerJson`
+
+Specifies a complete Envoy listener for Consul to deliver in place of the main public listener that the proxy uses to accept inbound connections. Refer to [escape-hatch overrides](/consul/docs/connect/proxies/envoy#escape-hatch-overrides) for more information
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.dynamicConfig.transparentProxy`
+
+Specifies additional configurations for operating proxies in transparent proxy mode.  Refer to [transparent proxy configuration reference](/consul/docs/connect/proxies/proxy-config-reference#transparent-proxy-configuration-reference) for more information.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.dynamicConfig.transparentProxy.dialedDirectly`
+
+Determines whether this proxy instance's IP address can be dialed directly by transparent proxies. Transparent proxies typically dial upstreams using the _virtual_ tagged address, which load balances across instances. A database cluster with a leader is an example where dialing individual instances can be helpful.
+
+#### Values
+
+- Default: `false`
+- Data type: Boolean
+
+### `spec.dynamicConfig.transparentProxy.outboundListenerPort`
+
+Specifies the port the proxy listens on for outbound traffic to capture and redirect.
+
+#### Values
+
+- Default: `15001`
+- Data type: Integer
+
+## Examples
+
+The following examples demonstrate common ProxyConfiguration CRD configuration patterns for specific use cases.
+
+### Set a timeout on a subset of proxies
+
+The following example configures sidecar proxies scheduled with workloads whose names begin with `static-server-`. When these workloads attempt connections with the local `web` application, both requests and responses time out after 123 second.
+
+```yaml
+apiVersion: mesh.consul.hashicorp.com/v2beta1
+kind: ProxyConfiguration
+metadata:
+  name: static-server-override-one
+spec:
+  workloads:
+    prefixes:
+    - "static-server-"
+  bootstrapConfig:
+    statsBindAddr: "127.0.0.1:6666"
+  dynamicConfig:
+    # Only the web port should be enabled using the TPs
+    localConnection:
+      web:
+        connectTimeout: "123s" # This ALWAYS has to end in 's'. If you want ms, you need to use "0.123s"
+        requestTimeout: "123s"
+```
diff --git a/website/content/docs/k8s/multiport/reference/resource-command.mdx b/website/content/docs/k8s/multiport/reference/resource-command.mdx
new file mode 100644
index 0000000000000..b7845787e3aba
--- /dev/null
+++ b/website/content/docs/k8s/multiport/reference/resource-command.mdx
@@ -0,0 +1,395 @@
+---
+layout: commands
+page_title: 'Commands: Resource'
+description: >-
+  The `consul resource` command interacts with Consul's v2 catalog of services and its resources. It exposes top-level commands for reading and filtering data from the registry.
+---
+
+# Consul Resource
+
+Command: `consul resource`
+
+Use the `resource` command to apply, list, read, and delete resources when interacting with Consul's v2 catalog through the command line. For more information, refer to [v2 catalog API](/consul/docs/concept/catalog/v2).
+
+The `consul resource` command has usage limitations in Consul v1.17.0. The CLI does not accept partition, namespace, and peer arguments, but the v2 catalog outputs this information when you add the `read` or `list` subcommand. In addition, do not use the `apply` and `delete` commands with Consul on Kubernetes in this release. Use the `kubectl` command to apply or delete resources instead. Refer to [configure multi-port services](/consul/docs/k8s/multiport/configure) for an example of the workflow to apply resources.
+
+## Usage
+
+```text
+Usage: consul resource  [options]
+
+  # ...
+
+Subcommands:
+
+    apply     Write or update resource information
+    delete    Delete resource information
+    list      Read all resources by type
+    read      Read resource information
+```
+
+On Kubernetes deployments, you must use a `kubectl exec` command to open a shell to the Consul server's container before you can run this Consul CLI command.
+
+## Subcommands
+
+You can issue the following subcommands with the `consul resource` command.
+
+### `apply`
+
+`consul resource apply` writes or updates a resource at a given file path.
+
+The following table shows the required [ACLs permission](/consul/api-docs/api-structure#authentication) to run the `apply` command:
+
+| ACL Required |
+| ------------ |
+| `operator:write`  |
+
+#### Command Options
+
+- `-f=` - (Required) The path to the file that defines the Consul resource. When the file that defines the resource is in the current working directory, you may optionally omit this flag and pass the resource filename only.
+
+#### Example usage
+
+The following command applies a traffic permissions resource to Consul that restricts service-to-service communication to authorized services only.
+
+```shell-session hideClipboard
+$ consul resource apply -f=trafficpermissions.hcl
+```
+
+### `delete`
+
+`consul resource delete` removes a Consul resource at a given file path.
+
+The following table shows the required [ACL permissions](/consul/api-docs/api-structure#authentication) to run the `delete` command:
+
+| ACL Required |
+| ------------ |
+| `operator:write`  |
+
+#### Command Options
+
+- `-f=` - (Required) The path to the file that defines the Consul resource. When the file that defines the resource is in the current working directory, you may optionally omit this flag and pass the resource filename only.
+
+#### Example usage
+
+The following command removes a traffic permissions resource from Consul that restricts service-to-service communication to authorized services only.
+
+```shell-session hideClipboard
+$ consul resource delete -f=trafficpermissions.hcl
+```
+
+### `list`
+
+`consul resource list` outputs information about resources according to the type of resource and the location where the resource is applied. 
+
+This command must be issued with a resource type. By formatting the type on the command line as `group.groupVersion.kind`, you can return all matching resources. For example, you can list information about services with `catalog.v2beta1.Service` and TCP routes with `mesh.v2beta1.TCPRoute`. Refer to [v2 catalog](/consul/docs/architecture/catalog/v2#catalog-structure) for more information.
+
+Do not include a resource name when listing resources.
+
+The following table shows the required [ACL permissions](/consul/api-docs/api-structure#authentication) to run the `list` command:
+
+| ACL Required |
+| ------------ |
+| `operator:read`  |
+
+#### Command Options
+
+The following flags enable you to filter results.
+
+- `-partition=` - The partition where the resources apply.
+- `-namespace=` - The namespace where the resources apply.
+- `-peer=` - The clusters with established cluster peering connections where the resources apply.
+
+#### Example usage
+
+The following command lists resources that apply to services registered with the v2 catalog API, and includes a sample output for the `api` and `web` services registered in [configure multi-port services](/consul/docs/k8s/multiport/configure):
+
+```shell-session hideClipboard
+$ consul resource list catalog.v2beta1.Service
+
+{
+    "resources": [
+        {
+            "data": {
+                "ports": [
+                    {
+                        "protocol": "PROTOCOL_TCP",
+                        "targetPort": "api",
+                        "virtualPort": 80
+                    },
+                    {
+                        "protocol": "PROTOCOL_MESH",
+                        "targetPort": "mesh"
+                    }
+                ],
+                "virtualIps": [
+                    "10.96.216.242"
+                ],
+                "workloads": {
+                    "prefixes": [
+                        "api-7c86cd8cb9"
+                    ]
+                }
+            },
+            "generation": "01HE8QWYFCTNEC2Q5JXKNXH6QW",
+            "id": {
+                "name": "api",
+                "tenancy": {
+                    "namespace": "default",
+                    "partition": "default",
+                    "peerName": "local"
+                },
+                "type": {
+                    "group": "catalog",
+                    "groupVersion": "v2beta1",
+                    "kind": "Service"
+                },
+                "uid": "01HE8QWYFCTNEC2Q5JXJ97M429"
+            },
+            "metadata": {
+                "k8s-namespace": "default",
+                "managed-by": "consul-k8s-endpoints-controller-v2"
+            },
+            "status": {
+                "consul.io/endpoint-manager": {
+                    "conditions": [
+                        {
+                            "message": "A valid workload selector is present within the service.",
+                            "reason": "SelectorFound",
+                            "state": "STATE_TRUE",
+                            "type": "EndpointsManaged"
+                        },
+                        {
+                            "message": "Found workload identities associated with this service: \"api\".",
+                            "reason": "WorkloadIdentitiesFound",
+                            "state": "STATE_TRUE",
+                            "type": "BoundIdentities"
+                        }
+                    ],
+                    "observedGeneration": "01HE8QWYFCTNEC2Q5JXKNXH6QW",
+                    "updatedAt": "2023-11-02T19:24:27.295564638Z"
+                }
+            },
+            "version": "118"
+        },
+        {
+            "data": {
+                "ports": [
+                    {
+                        "protocol": "PROTOCOL_TCP",
+                        "targetPort": "admin",
+                        "virtualPort": 90
+                    },
+                    {
+                        "protocol": "PROTOCOL_MESH",
+                        "targetPort": "mesh"
+                    }
+                ],
+                "virtualIps": [
+                    "10.96.231.41"
+                ],
+                "workloads": {
+                    "prefixes": [
+                        "api-7c86cd8cb9"
+                    ]
+                }
+            },
+            "generation": "01HE8QWYFJCXYXT2F4SBZE95Q4",
+            "id": {
+                "name": "api-admin",
+                "tenancy": {
+                    "namespace": "default",
+                    "partition": "default",
+                    "peerName": "local"
+                },
+                "type": {
+                    "group": "catalog",
+                    "groupVersion": "v2beta1",
+                    "kind": "Service"
+                },
+                "uid": "01HE8QWYFJCXYXT2F4SAHV7KG8"
+            },
+            "metadata": {
+                "k8s-namespace": "default",
+                "managed-by": "consul-k8s-endpoints-controller-v2"
+            },
+            "status": {
+                "consul.io/endpoint-manager": {
+                    "conditions": [
+                        {
+                            "message": "A valid workload selector is present within the service.",
+                            "reason": "SelectorFound",
+                            "state": "STATE_TRUE",
+                            "type": "EndpointsManaged"
+                        },
+                        {
+                            "message": "Found workload identities associated with this service: \"api\".",
+                            "reason": "WorkloadIdentitiesFound",
+                            "state": "STATE_TRUE",
+                            "type": "BoundIdentities"
+                        }
+                    ],
+                    "observedGeneration": "01HE8QWYFJCXYXT2F4SBZE95Q4",
+                    "updatedAt": "2023-11-02T19:24:27.589881680Z"
+                }
+            },
+            "version": "122"
+        },
+        {
+            "data": {
+                "ports": [
+                    {
+                        "protocol": "PROTOCOL_TCP",
+                        "targetPort": "80",
+                        "virtualPort": 80
+                    },
+                    {
+                        "protocol": "PROTOCOL_MESH",
+                        "targetPort": "mesh"
+                    }
+                ],
+                "virtualIps": [
+                    "10.96.157.170"
+                ],
+                "workloads": {
+                    "prefixes": [
+                        "web-6fd5c8bf57"
+                    ]
+                }
+            },
+            "generation": "01HE8QWYA9RSW2RS8GS5P538ZB",
+            "id": {
+                "name": "web",
+                "tenancy": {
+                    "namespace": "default",
+                    "partition": "default",
+                    "peerName": "local"
+                },
+                "type": {
+                    "group": "catalog",
+                    "groupVersion": "v2beta1",
+                    "kind": "Service"
+                },
+                "uid": "01HE8QWYA9RSW2RS8GS3922SK0"
+            },
+            "metadata": {
+                "k8s-namespace": "default",
+                "managed-by": "consul-k8s-endpoints-controller-v2"
+            },
+            "status": {
+                "consul.io/endpoint-manager": {
+                    "conditions": [
+                        {
+                            "message": "A valid workload selector is present within the service.",
+                            "reason": "SelectorFound",
+                            "state": "STATE_TRUE",
+                            "type": "EndpointsManaged"
+                        },
+                        {
+                            "message": "Found workload identities associated with this service: \"web\".",
+                            "reason": "WorkloadIdentitiesFound",
+                            "state": "STATE_TRUE",
+                            "type": "BoundIdentities"
+                        }
+                    ],
+                    "observedGeneration": "01HE8QWYA9RSW2RS8GS5P538ZB",
+                    "updatedAt": "2023-11-02T19:24:27.190972222Z"
+                }
+            },
+            "version": "115"
+        }
+    ]
+}
+```
+
+### `read`
+
+`consul resource read` outputs information about resources according to the type and name of the resource.
+
+This command must be issued with a resource type and a resource name. By formatting the type on the command line as `group.groupVersion.kind`, you can return all matching resources. For example, you can read information about services with `catalog.v2beta1.Service`, TCP routes with `mesh.v2beta1.TCPRoute`, and traffic permissions with `auth.v2beta1.TrafficPermissions`. Refer to [v2 catalog](/consul/docs/architecture/catalog/v2#catalog-structure) for more information. 
+
+The following table shows the required [ACL permissions](/consul/api-docs/api-structure#authentication) to run the `read` command:
+
+| ACL Required |
+| ------------ |
+| `operator:read`  |
+
+#### Command Options
+
+- `-partition=` - The partition where the resource applies.
+- `-namespace=` - The namespace where the resource applies.
+- `-peer=` - The clusters with established cluster peering connections where the resource applies.
+- `-stale` - Permits any Consul server to respond to the request. This flag enables for lower latency and higher throughput, but may result in stale data. This option has no effect on non-read operations.
+- `-token` - A Consul ACL token to include with the request.
+
+#### Example usage
+
+The following example demonstrates a command to read the `web` service and includes an example output that includes information such as ports, virtual IPs, and status.
+
+```shell-session hideClipboard
+$ consul resource read catalog.v2beta1.Service web
+
+{
+    "data": {
+        "ports": [
+            {
+                "protocol": "PROTOCOL_TCP",
+                "targetPort": "80",
+                "virtualPort": 80
+            },
+            {
+                "protocol": "PROTOCOL_MESH",
+                "targetPort": "mesh"
+            }
+        ],
+        "virtualIps": [
+            "10.96.98.157"
+        ],
+        "workloads": {
+            "prefixes": [
+                "web-6fd5c8bf57"
+            ]
+        }
+    },
+    "generation": "01HE6MPDXC1J6ZMEMPN1460Z6K",
+    "id": {
+        "name": "web",
+        "tenancy": {
+            "namespace": "default",
+            "partition": "default",
+            "peerName": "local"
+        },
+        "type": {
+            "group": "catalog",
+            "groupVersion": "v2beta1",
+            "kind": "Service"
+        },
+        "uid": "01HE6MPDXC1J6ZMEMPN0648FVB"
+    },
+    "metadata": {
+        "k8s-namespace": "default",
+        "managed-by": "consul-k8s-endpoints-controller-v2"
+    },
+    "status": {
+        "consul.io/endpoint-manager": {
+            "conditions": [
+                {
+                    "message": "A valid workload selector is present within the service.",
+                    "reason": "SelectorFound",
+                    "state": "STATE_TRUE",
+                    "type": "EndpointsManaged"
+                },
+                {
+                    "message": "Found workload identities associated with this service: \"web\".",
+                    "reason": "WorkloadIdentitiesFound",
+                    "state": "STATE_TRUE",
+                    "type": "BoundIdentities"
+                }
+            ],
+            "observedGeneration": "01HE6MPDXC1J6ZMEMPN1460Z6K",
+            "updatedAt": "2023-11-01T23:49:59.172604219Z"
+        }
+    },
+    "version": "137"
+}
+```
diff --git a/website/content/docs/k8s/multiport/reference/tcproute.mdx b/website/content/docs/k8s/multiport/reference/tcproute.mdx
new file mode 100644
index 0000000000000..9dd8a4ca1bedb
--- /dev/null
+++ b/website/content/docs/k8s/multiport/reference/tcproute.mdx
@@ -0,0 +1,341 @@
+---
+layout: docs
+page_title: TCPRoute resource configuration reference
+description: The TCPRoute resource CRD configures L4 TCP behavior within the service mesh. TCPRoute is a GAMMA resource that requires the v2 catalog API. Learn how to configure the TCPRoute CRD with specifications and example configurations.
+---
+
+# TCPRoute resource configuration reference
+
+This page provides reference information for the `TCPRoute` resource, which defines Transport Layer (L4) TCP traffic within the service mesh.
+
+This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/catalog/v2). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog/v1). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/).
+
+## Configuration model
+
+The following list outlines field hierarchy, language-specific data types, and requirements in an TCP route CRD. Click on a property name to view additional details, including default values.
+
+
+
+
+
+- [`apiVersion`](#apiversion): string | required | must be set to `mesh.consul.hashicorp.com/v2beta1`
+- [`kind`](#kind): string | required | must be set to `TCPRoute`
+- [`metadata`](#metadata): map  | required
+  - [`name`](#metadata-name): string | required
+  - [`namespace`](#metadata-namespace): string | optional 
+- [`spec`](#spec): map | required
+  - [`parentRefs`](#spec-parentrefs): map | required
+    - [`port`](#spec-parentrefs-port): string
+    - [`ref`](#spec-parentrefs-ref):  string | required
+      - [`name`](#spec-parentrefs-ref-name): string
+      - [`type`](#spec-parentrefs-ref-type): map
+         - [`group`](#spec-parentrefs-ref-type): string
+         - [`groupVersion`](#spec-parentrefs-ref-type): string
+         - [`kind`](#spec-parentrefs-ref-type): string
+  - [`rules`](#spec-rules): map | required
+    - [`backendRefs`](#spec-rules-backendrefs): map
+      - [`backendRef`](#spec-rules-backendrefs-backendref): map
+        - [`datacenter`](#spec-rules-backendrefs-backendref-datacenter): string
+        - [`port`](#spec-rules-backendrefs-backendref-port): string
+        - [`ref`](#spec-rules-backendrefs-backendref-ref): map
+          - [`name`](#spec-rules-backendrefs-backendref-ref-name): string
+          - [`type`](#spec-rules-backendrefs-backendref-ref-type): map
+            - [`group`](#spec-rules-backendrefs-backendref-ref-type): string
+            - [`groupVersion`](#spec-rules-backendrefs-backendref-ref-type): string
+            - [`kind`](#spec-rules-backendrefs-backendref-ref-type): string
+      - [`weight`](#spec-rules-backendrefs-weight): number
+
+
+
+
+## Complete configuration
+
+When every field is defined, a TCP route CRD has the following form:
+
+```yaml
+apiVersion: mesh.consul.hashicorp.com/v2beta1        # required 
+kind: TCPRoute                                       # required
+metadata:
+  name: 
+  namespace: 
+spec:
+  parentRefs:
+    port: 
+    - ref:
+      name: 
+      type: 
+        group: 
+        groupVersion: 
+        kind: 
+  rules:
+    - backendRefs:
+      - backendRef:
+        datacenter: 
+        port: 
+        ref:
+          name: 
+          type:
+            group: 
+            groupVersion: 
+            kind: 
+      weight: 1
+```
+
+## Specification
+
+This section provides details about the fields you can configure in the `TCPRoute` custom resource definition (CRD).
+
+### `apiVersion`
+
+Specifies the version of the Consul API for integrating with Kubernetes. The value must be `mesh.consul.hashicorp.com/v2beta1`.
+
+#### Values
+
+- Default: None
+- This field is required.
+- String value that must be set to `mesh.consul.hashicorp.com/v2beta1`.
+
+### `kind`
+
+Specifies the type of CRD to implement. Must be set to `TCPRoute`.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: String value that must be set to `TCPRoute`.
+
+### `metadata`
+
+Map that contains an arbitrary name for the CRD and the namespace it applies to.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `metadata.name`
+
+Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: String
+
+### `metadata.namespace` 
+
+Specifies the namespace that the service resolver applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec`
+
+Map that contains the details about the `TCPRoute` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children.
+
+When using this CRD, the `spec` field closely resembles the `TCPRoute` GAMMA resource.  Refer to [TCPRoute in the Kubernetes documentation](https://gateway-api.sigs.k8s.io/references/spec/#gateway.networking.k8s.io/v1alpha2.TCPRoute).
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: Map
+
+### `spec.parentRefs`
+
+Specifies the services and other resources to attach the route to. You can only define one `parentsRefs` configuration for each route. To attach the route to multiple resources, specify additional [`spec.parentRefs.ref`](#spec-parentrefs-ref) configurations in the `parentsRefs` block. You can only specify the name of one port for the route. Any resources that send traffic through the route use the same port.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: Map
+
+### `spec.parentRefs.port`
+
+Specifies the name of the port that the configuration applies to.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.parentRefs.ref`
+
+Specifies the resource that the route attaches to.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.parentRefs.ref.name`
+
+Specifies the user-defined name of the resource that the configuration applies to.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.parentRefs.ref.type`
+
+Specifies the type of resource that the configuration applies to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`.
+
+#### Values
+
+- Default: None
+- Data type: Map containing the following parameters:
+
+  | Parameter     | Description                                                          | Data type | Default  |
+  | :------------ | :------------------------------------------------------------------- | :-------- | :------- |
+  | `group`   | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String    | None     |
+  | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None     |
+  | `kind`    | Specifies the kind of the Kubernetes object the resource applies to. To reference a service in the Consul catalog, set this parameter to `Service`.                | String    | None     |
+
+### `spec.rules`
+
+Specifies rules for sidecar proxies to direct a service's TCP traffic within the service mesh.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.rules.backendRefs`
+
+Specifies the Kubernetes Service backend to direct TCP traffic to when a request matches the service described in [`spec.parentRefs`](#spec-parentrefs). The Service backend is the collection of endpoint IPs for the service. Refer to [the Kubernetes Gateway API specification](https://gateway-api.sigs.k8s.io/concepts/gamma/#an-overview-of-the-gateway-api-for-service-mesh) for more information about Service backends.
+
+When a valid Service backend cannot be reached and no additional filters apply, traffic that matches the rule returns a 500 status code.
+
+When different Service backends are specified in [`spec.rules.backendRefs.weight`](#spec-rules-backendrefs-weight) and one of the backends is invalid, Consul continues to apply the specified weights instead of adjusting the relative weights to exclude traffic to the invalid backend. For example, when traffic is configured in a 50-50 split between `api` and `admin` and no valid endpoints for `admin` can be reached, the 50% of traffic intended for `admin` returns with a 500 status code.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.rules.backendRefs.backendRef`
+
+Specifies an individual Service backend where matching requests should be sent.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.rules.backendRefs.backendRef.datacenter`
+
+Specifies the name of the Consul datacenter that registered the Service backend that the configuration routes traffic to.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.rules.backendRefs.backendRef.port`
+
+Specifies the name of the port for the Consul service that the configuration routes traffic to.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.rules.backendRefs.backendRef.ref`
+
+The Consul service that the configuration routes traffic to.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.rules.backendRefs.backendRef.ref.name`
+
+Specifies the user-defined name of the resource that the configuration routes traffic to.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.rules.backendRefs.backendRef.ref.type`
+
+Specifies the type of resource that the configuration routes traffic to. To reference a service in the Consul catalog, configure the resource type as `catalog.v2beta1.Service`.
+
+#### Values
+
+- Default: None
+- Data type: Map containing the following parameters:
+
+  | Parameter     | Description                                                          | Data type | Default  |
+  | :------------ | :------------------------------------------------------------------- | :-------- | :------- |
+  | `group`   | Specifies a group for the resource type within the Kubernetes cluster. To reference a service in the Consul catalog, set this parameter to `catalog`. | String    | None     |
+  | `groupVersion` | Specifies a groupVersion for the resource type within the Kubenretes cluster. To reference a service in the Consul catalog, set this parameter to `v2beta1`. | String | None     |
+  | `kind`    | Specifies the kind of the Kubernetes object for the resource. To reference a service in the Consul catalog, set this parameter to `Service`.                | String    | None     |
+
+### `spec.rules.backendRefs.weight`
+
+Specifies the proportion of requests routed to the specified service. 
+
+This proportion is relative to the sum of all weights in the [`spec.rules.backendRefs`](#spec-rules-backendrefs) block. As a result, weights do not need to add up to 100. When only one backend is specified and the weight is greater then 0, Consul forwards 100% of traffic to the backend. 
+
+When this parameter is not specified, Consul defaults to `1`.
+
+#### Values
+
+- Default: `1`
+- Data type: Integer
+
+## Examples
+
+The following examples demonstrate common TCPRoute CRD configuration patterns for specific use cases.
+
+### Split TCP traffic between two ports
+
+The following example splits traffic for the `api` service. TCP traffic for services registered to the Consul catalog that are available at the `api` port is split so that 50% of the traffic routes to the service at the `api` port and 50% routes to the service at the `admin` port.
+
+```yaml
+apiVersion: mesh.consul.hashicorp.com/v2beta1
+kind: TCPRoute
+metadata:
+  name: api-split
+  namespace: default
+spec:
+  parentRefs:
+    - ref:
+        type: 
+          group: catalog
+          groupVersion: v2beta1
+          kind: Service
+        name: api
+      # The configuration targets the workload port, not the service port.
+      port: "api"
+  rules:
+    - backendRefs:
+      - backendRef:
+          ref: 
+            type:
+              group: catalog
+              groupVersion: v2beta1
+              kind: Service
+            name: api
+          # The configuration targets the workload port, not the service port.
+          port: "api"
+        weight: 50
+      - backendRef:
+          ref: 
+            type:
+              group: catalog
+              groupVersion: v2beta1
+              kind: Service
+            name: api
+          # The configuration targets the workload port, not the service port.
+          port: "admin"
+        weight: 50
+```
\ No newline at end of file
diff --git a/website/content/docs/k8s/multiport/reference/trafficpermissions.mdx b/website/content/docs/k8s/multiport/reference/trafficpermissions.mdx
new file mode 100644
index 0000000000000..0eae49e88b47e
--- /dev/null
+++ b/website/content/docs/k8s/multiport/reference/trafficpermissions.mdx
@@ -0,0 +1,242 @@
+---
+layout: docs
+page_title: TrafficPermissions resource configuration reference
+description: The TrafficPermissions CRD defines rules for allowing and denying traffic between services within the service mesh. Learn how to configure traffic permissions for the v2 catalog to authorize service-to-service communication in a network with zero-trust security.
+---
+
+# TrafficPermissions configuration reference
+
+This page provides reference information for the `TrafficPermissions` resource, which authorizes east-west traffic between services within the service mesh. The traffic permissions CRD replaces the service intentions CRD when using the v2 catalog API. Refer to [changes to Consul's existing architecture](/consul/docs/architecture/catalog/v2#changes-to-consul-s-existing-architecture) for more information.
+
+This custom resource definition (CRD) describes a resource related to the [Kubernetes GAMMA initiative](https://gateway-api.sigs.k8s.io/concepts/gamma/) that requires the [v2 catalog API](/consul/docs/architecture/catalog/v2). It is not compatible with the [v1 catalog API](/consul/docs/architecture/catalog/v1). For more information about GAMMA resources, refer to the [Kubernetes Gateway API documentation](https://gateway-api.sigs.k8s.io/concepts/gamma/).
+
+## Configuration model
+
+The following list outlines field hierarchy, language-specific data types, and requirements in a traffic permissions CRD. Click on a property name to view additional details, including default values.
+
+- [`apiVersion`](#apiversion): string | required | must be set to `auth.consul.hashicorp.com/v2beta1`
+- [`kind`](#kind): string | required | must be set to `TrafficPermissions`
+- [`metadata`](#metadata): map | required
+  - [`name`](#metadata-name): string | required
+  - [`namespace`](#metadata-namespace): string | optional 
+- [`spec`](#spec): map | required
+  - [`destination`](#spec-destination): map
+    - [`identityName`](#spec-destination-identityname): string
+  - [`action`](#spec-action): string
+  - [`permissions`](#spec-permissions): list of maps
+    - [`sources`](#spec-permissions-sources): map
+      - [`identityName`](#spec-permissions-sources-identityname): string
+    - [`destinationRules`](#spec-permissions-destinationrules):
+      - [`portNames`](#spec-permissions-destinationrules-portNames): array of strings
+
+## Complete configuration
+
+When every field is defined, a traffic permissions CRD has the following form:
+
+```yaml
+apiVersion: auth.consul.hashicorp.com/v2beta1    # required
+kind: TrafficPermissions                         # required
+metadata:
+  name: 
+  namespace: 
+spec:
+  destination:
+    identityName: 
+  action: allow
+  permissions:
+    - sources:
+      identityName:  
+    destinationRules:
+      portNames: 
+        - 
+```
+
+## Specification
+
+This section provides details about the fields you can configure in the `TrafficPermissions` custom resource definition (CRD).
+
+### `apiVersion`
+
+Specifies the version of the Consul API for integrating with Kubernetes. The value must be `auth.consul.hashicorp.com/v2beta1`.
+
+#### Values
+
+- Default: None
+- This field is required.
+- String value that must be set to `auth.consul.hashicorp.com/v2beta1`.
+
+### `kind`
+
+Specifies the type of CRD to implement. Must be set to `TrafficPermissions`.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: String value that must be set to `TrafficPermissions`.
+
+### `metadata`
+
+Map that contains an arbitrary name for the CRD and the namespace it applies to.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `metadata.name`
+
+Specifies a name for the CRD. The name is metadata that you can use to reference the resource when performing Consul operations, such as using the `consul resource` command. Refer to [`consul resource`](/consul/docs/k8s/connect/multiport/reference/resource-command) for more information.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: String
+
+### `metadata.namespace` 
+
+Specifies the namespace that the service resolver applies to. Refer to [namespaces](/consul/docs/enterprise/namespaces) for more information.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec`
+
+Map that contains the details about the `TrafficPermissions` CRD. The `apiVersion`, `kind`, and `metadata` fields are siblings of the spec field. All other configurations are children.
+
+#### Values
+
+- Default: None
+- This field is required.
+- Data type: Map
+
+### `spec.destination`
+
+Specifies the proxies of the services where these traffic permissions apply.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.destination.identityName`
+
+Specifies the Workload identity for a service. The permissions you configure in this `TrafficPermissions` CRD apply to sidecar proxies when a request has this identity as their destination.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+### `spec.action`
+
+Specifies whether the proxy should _allow traffic_ or _deny traffic_ between the destination in [`spec.destination`](#spec-destination) and the sources in [`spec.permissions.sources`](#spec-permissions-sources).
+
+By default, Consul allows traffic between all services. When the Helm value `global.acls.manageSystemACLs` is set to `true`, then Consul operates in "default-deny" mode. In this mode, `TrafficPermissions` CRDs that allow traffic between services are required for service-to-service traffic.
+
+#### Values
+
+- Default: None
+- Data type: String that must contain one of the following values:
+
+  - `ACTION_ALLOW`
+  - `ACTION_DENY`
+
+### `spec.permissions`
+
+Permissions is a list of the traffic permissions Consul evaluates requests against. When the list contains more than one permission, Consul follows OR semantics to select the permission.
+
+#### Values
+
+- Default: None
+- Data type: List of maps
+
+### `spec.permissions.sources`
+
+Lists sources for traffic in the permission. This block contains information Consul uses to evaluate the service that originated the request when the sidecar proxy authorizes incoming traffic.
+
+To specify wildcard references in this block using `*`, omit all other fields. For example, you can apply traffic permissions to all namespaces using the wildcard, but you cannot specify an identity name, partition, peer, or sameness group in the same source.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.permissions.sources.identityName`
+
+Specifies the Workload identity for the service that originates the request.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.permissions.destinationRules`
+
+Specifies L7 properties to match against when Consul enforces traffic permissions.
+
+When [`spec.action`](#spec-action) _allows traffic_, Consul authorizes requests to the destination service when the request matches one or more rules defined in this block. Requests that do not match any rules are denied.
+
+When [`spec.action`](#spec-action) _denies traffic_, Consul denies authorization to requests that match one or more rules defined in this block. Requests that do not match any rules are allowed.
+
+#### Values
+
+- Default: None
+- Data type: Map
+
+### `spec.permissions.destinationRules.portNames`
+
+Specifies a port name that the Kubernetes Service exposes at the destination.
+
+#### Values
+
+- Default: None
+- Data type: String
+
+## Examples
+
+The following examples demonstrate common `TrafficPermissions` CRD configuration patterns for specific use cases.
+
+### Allow traffic to multiple ports
+
+The following example configures traffic permissions to allow traffic when the `web` service makes a request to the `api` service on the `api` port or `admin` port.
+
+```yaml
+apiVersion: auth.consul.hashicorp.com/v2beta1
+kind: TrafficPermissions
+metadata:
+  name: api-allow-web-all
+spec:
+  destination:
+    identityName: "api"
+  action: ACTION_ALLOW
+  permissions:
+    - sources:
+        - identityName: "web"
+      destinationRules:
+        - portNames: ["api", "admin"]
+
+```
+
+### Deny traffic between a service and a specific port
+
+The following example configures traffic permissions to deny traffic when the `web` service makes a request to the `api` service on the `admin` port.
+
+```yaml
+apiVersion: auth.consul.hashicorp.com/v2beta1
+kind: TrafficPermissions
+metadata:
+  name: web-to-admin-port-deny
+spec:
+  destination:
+    identityName: api
+  action: ACTION_DENY
+  permissions:
+    - sources:
+        - identityName: web
+      destinationRules:
+        - portNames: ["admin"]
+```
diff --git a/website/content/docs/k8s/multiport/traffic-split.mdx b/website/content/docs/k8s/multiport/traffic-split.mdx
new file mode 100644
index 0000000000000..23a714f124668
--- /dev/null
+++ b/website/content/docs/k8s/multiport/traffic-split.mdx
@@ -0,0 +1,164 @@
+---
+layout: docs
+page_title: Split traffic between multi-port services 
+description: Learn how to configure Consul to split TCP traffic between two ports of a multi-port service using the TCPRoute resource and the v2 catalog API
+---
+
+# Split TCP traffic between multi-port services
+
+
+
+Multi-port services are part of a beta release. This documentation supports testing and development scenarios. Do not use multi-port services or the v2 catalog API in secure production environments.
+
+
+
+This page describes the process for splitting TCP, HTTP, and gRPC traffic between two ports of a multi-port service. It includes an example TCPRoute resource configuration to demonstrate Consul's multi-port features.
+
+## Prerequisites
+
+Splitting traffic between two ports of a multi-port service requires the [v2 catalog API](/consul/docs/architecture/catalog/v2).
+
+In addition, how you define a multi-port service affects how Services are addressed in Kubernetes. The instructions on this page offer examples for two configuration methods:
+
+- **Method 1**: Define a single Kubernetes Service that exposes multiple ports
+- **Method 2**: Define multiple Kubernetes Services that expose individual ports
+
+For guidance on enabling the v2 catalog, deploying multi-port services using these methods, and applying traffic permissions to the services, refer to [configure multi-port services](/consul/docs/k8s/multiport/configure).
+
+## Overview
+
+Complete the following steps to implement a split in TCP traffic between two services:
+
+1. Define the resource's behavior in a custom resource definition (CRD).
+1. Apply the resource to your cluster.
+
+## Define route resource
+
+The following example splits traffic for the services in the `api` Pod.
+
+
+
+
+
+TCP traffic for services registered to the Consul catalog that are available at the `admin` port is split so that 50% of the traffic routes to the service at the `api` port and 50% routes to the service at the `admin` port.
+
+
+
+```yaml
+apiVersion: mesh.consul.hashicorp.com/v2beta1
+kind: TCPRoute
+metadata:
+  name: api-split
+spec:
+  parentRefs:
+    - ref:
+        type: 
+          group: catalog
+          groupVersion: v2beta1
+          kind: Service
+        name: api
+      port: "admin"
+  rules:
+    - backendRefs:
+      - backendRef:
+          ref: 
+            type:
+              group: catalog
+              groupVersion: v2beta1
+              kind: Service
+            name: api
+          port: "api"
+        weight: 50
+      - backendRef:
+          ref: 
+            type:
+              group: catalog
+              groupVersion: v2beta1
+              kind: Service
+            name: api
+          port: "admin"
+        weight: 50
+```
+
+
+
+
+
+
+TCP traffic for services registered to the Consul catalog that are available at the `api-admin` port is split so that 50% of the traffic routes to the service at the `api` port and 50% routes to the service at the `api-admin` port.
+
+
+
+```yaml
+apiVersion: mesh.consul.hashicorp.com/v2beta1
+kind: TCPRoute
+metadata:
+  name: api-split
+spec:
+  parentRefs:
+    - ref:
+        type: 
+          group: catalog
+          groupVersion: v2beta1
+          kind: Service
+        name: api-admin
+      port: "admin"
+  rules:
+    - backendRefs:
+      - backendRef:
+          ref: 
+            type:
+              group: catalog
+              groupVersion: v2beta1
+              kind: Service
+            name: api
+          port: "api"
+        weight: 50
+      - backendRef:
+          ref: 
+            type:
+              group: catalog
+              groupVersion: v2beta1
+              kind: Service
+            name: api-admin
+          port: "admin"
+        weight: 50
+```
+
+
+
+
+
+
+## Apply the resource
+
+Use the `kubectl` command to apply the resource to your Consul cluster.
+
+```shell-session
+$ kubectl apply -f api-split.yaml
+```
+
+
+
+
+
+Then, open a shell session in the `web` container and test the `api` service on port 90.
+
+```shell-session
+$ kubectl exec -it ${WEB_POD} -c web -- curl api:90
+```
+
+
+
+
+
+Then, open a shell session in the `web` container and test the `api-admin` service on port 90.
+
+```shell-session
+$ kubectl exec -it ${WEB_POD} -c web -- curl api-admin:90
+```
+
+
+
+
+Half of the traffic should respond with the `hello world` response from port 80, instead of port 90's response of `hello world from 9090 admin`. Repeat the command several times to verify that you receive both responses.
\ No newline at end of file
diff --git a/website/content/docs/services/discovery/dns-configuration.mdx b/website/content/docs/services/discovery/dns-configuration.mdx
index 5a0d890e79bff..369f8fe50ff79 100644
--- a/website/content/docs/services/discovery/dns-configuration.mdx
+++ b/website/content/docs/services/discovery/dns-configuration.mdx
@@ -16,7 +16,7 @@ The Consul DNS is the primary interface for querying records when Consul service
 By default, the Consul DNS listens for queries at `127.0.0.1:8600` and uses the `consul` domain. Specify the following parameters in the agent configuration to determine DNS behavior when querying services:
 
 - [`client_addr`](/consul/docs/agent/config/config-files#client_addr)
-- [`ports.dns`](/consul/docs/agent/config/config-files#dns_port) : Consul does not use port `53`, which is typically reserved for the default port for DNS resolvers, by default because it requires an escalated privilege to bind to. 
+- [`ports.dns`](/consul/docs/agent/config/config-files#dns_port) : Consul does not use port `53`, which is typically reserved for the default port for DNS resolvers, by default because it requires an escalated privilege to bind to.
 - [`recursors`](/consul/docs/agent/config/config-files#recursors)
 - [`domain`](/consul/docs/agent/config/config-files#domain)
 - [`alt_domain`](/consul/docs/agent/config/config-files#alt_domain)
diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json
index 90b167036c68d..2bc2266414ab8 100644
--- a/website/data/docs-nav-data.json
+++ b/website/data/docs-nav-data.json
@@ -102,6 +102,19 @@
         "title": "Overview",
         "path": "architecture"
       },
+      {
+        "title": "Catalog",
+        "routes": [
+          {
+            "title": "v1 API",
+            "path": "architecture/catalog/v1"
+          },
+          {
+            "title": "v2 API",
+            "path": "architecture/catalog/v2"
+          }
+        ]
+      },
       {
         "title": "Improving Consul Resilience",
         "path": "architecture/improving-consul-resilience"
@@ -1532,6 +1545,39 @@
           {
             "title": "Configure multi-port services",
             "path": "k8s/multiport/configure"
+          },
+          {
+            "title": "Split TCP traffic between multi-port services",
+            "path": "k8s/multiport/traffic-split"
+          },
+          {
+            "title": "Reference",
+            "routes": [
+              {
+                "title": "Consul resource command",
+                "path": "k8s/multiport/reference/resource-command"
+              },
+              {
+                "title": "GRPCRoute resource",
+                "path": "k8s/multiport/reference/grpcroute"
+              },
+              {
+                "title": "HTTPRoute resource",
+                "path": "k8s/multiport/reference/httproute"
+              },
+              {
+                "title": "ProxyConfiguration resource",
+                "path": "k8s/multiport/reference/proxyconfiguration"
+              },
+              {
+                "title": "TCPRoute resource",
+                "path": "k8s/multiport/reference/tcproute"
+              },
+              {
+                "title": "TrafficPermissions resource",
+                "path": "k8s/multiport/reference/trafficpermissions"
+              }
+            ]
           }
         ]
       },
@@ -2004,4 +2050,4 @@
     "path": "guides",
     "hidden": true
   }
-]
+]
\ No newline at end of file