diff --git a/.changelog/18994.txt b/.changelog/18994.txt index f28381721d54..3f80f3457671 100644 --- a/.changelog/18994.txt +++ b/.changelog/18994.txt @@ -12,12 +12,6 @@ environments. * 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. * HCP Consul does not support multi-port services or the v2 catalog API in this release. -* The v2 API only supports transparent proxy mode where services that have permissions to connect to each other can use - Kube DNS to connect. - -### Known Issues -* When using the v2 API with transparent proxy, Kubernetes pods cannot use L7 liveness, readiness, or startup probes. - [[Catalog resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/catalog/internal/controllers) [[Mesh resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/mesh/internal/controllers) diff --git a/.changelog/19225.txt b/.changelog/19225.txt new file mode 100644 index 000000000000..d4c4d156d454 --- /dev/null +++ b/.changelog/19225.txt @@ -0,0 +1,9 @@ +```release-note:security +Upgrade Go to 1.20.10. +This resolves vulnerability [CVE-2023-39325](https://nvd.nist.gov/vuln/detail/CVE-2023-39325) +/ [CVE-2023-44487](https://nvd.nist.gov/vuln/detail/CVE-2023-44487)(`net/http`). +``` +```release-note:security +Update `golang.org/x/net` to v0.17.0 to address [CVE-2023-39325](https://nvd.nist.gov/vuln/detail/CVE-2023-39325) +/ [CVE-2023-44487](https://nvd.nist.gov/vuln/detail/CVE-2023-44487)(`x/net/http2`). +``` diff --git a/.changelog/19268.txt b/.changelog/19268.txt new file mode 100644 index 000000000000..2bb8f489e345 --- /dev/null +++ b/.changelog/19268.txt @@ -0,0 +1,3 @@ +```release-note:bug +Mesh Gateways: Fix a bug where replicated and peered mesh gateways with hostname-based WAN addresses fail to initialize. +``` diff --git a/.changelog/19274.txt b/.changelog/19274.txt new file mode 100644 index 000000000000..81c0b638b958 --- /dev/null +++ b/.changelog/19274.txt @@ -0,0 +1,3 @@ +```release-note:security +connect: update supported envoy versions to 1.24.12, 1.25.11, 1.26.6, 1.27.2 to address [CVE-2023-44487](https://github.com/envoyproxy/envoy/security/advisories/GHSA-jhv4-f7mr-xx76) +``` diff --git a/.changelog/19285.txt b/.changelog/19285.txt new file mode 100644 index 000000000000..52320702edb3 --- /dev/null +++ b/.changelog/19285.txt @@ -0,0 +1,7 @@ +```release-note:bug +ca: Fix bug with Vault CA provider where token renewal goroutines could leak if CA failed to initialize. +``` + +```release-note:bug +ca: Fix bug with Vault CA provider where renewing a retracted token would cause retries in a tight loop, degrading performance. +``` diff --git a/.changelog/19314.txt b/.changelog/19314.txt new file mode 100644 index 000000000000..c5f1346f3bfe --- /dev/null +++ b/.changelog/19314.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +raft: upgrade raft-wal library version to 0.4.1. +``` diff --git a/.changelog/19339.txt b/.changelog/19339.txt new file mode 100644 index 000000000000..884fb4a3bd16 --- /dev/null +++ b/.changelog/19339.txt @@ -0,0 +1,4 @@ +```release-note:bug +connect: Fix bug where uncleanly closed xDS connections would influence connection balancing for too long and prevent envoy instances from starting. Two new configuration fields +`performance.grpc_keepalive_timeout` and `performance.grpc_keepalive_interval` now exist to allow for configuration on how often these dead connections will be cleaned up. +``` diff --git a/.changelog/19389.txt b/.changelog/19389.txt new file mode 100644 index 000000000000..1fe521b85381 --- /dev/null +++ b/.changelog/19389.txt @@ -0,0 +1,3 @@ +```release-note:improvement +cli: stop simultaneous usage of -templated-policy and -templated-policy-file when creating a role or token. +``` \ No newline at end of file diff --git a/.changelog/19414.txt b/.changelog/19414.txt new file mode 100644 index 000000000000..416d8e559bc1 --- /dev/null +++ b/.changelog/19414.txt @@ -0,0 +1,4 @@ +```release-note:security +Upgrade `google.golang.org/grpc` to 1.56.3. +This resolves vulnerability [CVE-2023-44487](https://nvd.nist.gov/vuln/detail/CVE-2023-44487). +``` diff --git a/.changelog/19503.txt b/.changelog/19503.txt new file mode 100644 index 000000000000..cb89cfbec1e2 --- /dev/null +++ b/.changelog/19503.txt @@ -0,0 +1,3 @@ +```release-note:bug +wan-federation: Fix a bug where servers wan-federated through mesh-gateways could crash due to overlapping LAN IP addresses. +``` diff --git a/.changelog/_7406.txt b/.changelog/_7406.txt new file mode 100644 index 000000000000..b020a3a0e601 --- /dev/null +++ b/.changelog/_7406.txt @@ -0,0 +1,3 @@ +```release-note:bug +server: **(Enterprise Only)** Fixed an issue where snake case keys were rejected when configuring the control-plane-request-limit config entry +``` \ No newline at end of file diff --git a/.github/scripts/set_test_package_matrix.sh b/.github/scripts/set_test_package_matrix.sh index da8b6d563c37..3f8a389297f4 100755 --- a/.github/scripts/set_test_package_matrix.sh +++ b/.github/scripts/set_test_package_matrix.sh @@ -6,6 +6,6 @@ set -euo pipefail export RUNNER_COUNT=$1 # set matrix var to list of unique packages containing tests -matrix="$(go list -json="ImportPath,TestGoFiles" ./... | jq --compact-output '. | select(.TestGoFiles != null) | .ImportPath' | jq --slurp --compact-output '.' | jq --argjson runnercount $RUNNER_COUNT -cM '[_nwise(length / $runnercount | floor)]'))" +matrix="$(go list -json="ImportPath,TestGoFiles" ./... | jq --compact-output '. | select(.TestGoFiles != null) | .ImportPath' | shuf | jq --slurp --compact-output '.' | jq --argjson runnercount $RUNNER_COUNT -cM '[_nwise(length / $runnercount | floor)]'))" echo "matrix=${matrix}" >> "${GITHUB_OUTPUT}" diff --git a/.github/scripts/verify_envoy_version.sh b/.github/scripts/verify_envoy_version.sh index f9067eaa37f7..4bcbea4cabee 100755 --- a/.github/scripts/verify_envoy_version.sh +++ b/.github/scripts/verify_envoy_version.sh @@ -4,7 +4,7 @@ set -euo pipefail -current_branch=$GITHUB_REF +current_branch=$GITHUB_REF_NAME GITHUB_DEFAULT_BRANCH='main' if [ -z "$GITHUB_TOKEN" ]; then @@ -13,10 +13,15 @@ if [ -z "$GITHUB_TOKEN" ]; then fi if [ -z "$current_branch" ]; then - echo "GITHUB_REF must be set" + echo "GITHUB_REF_NAME must be set" exit 1 fi +if [[ "$SKIP_VERIFY_ENVOY_VERSION" = "true" ]]; then + echo -e "*************** VERIFY ENVOY VERSION IS DISABLED. To enable, update environment variable in Github settings *****************" + exit 0 +fi + # Get Consul and Envoy version SCRIPT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" pushd $SCRIPT_DIR/../.. # repository root @@ -76,7 +81,6 @@ released_envoy_version=$(get_latest_envoy_version) major_released_envoy_version="${released_envoy_version[@]:1:4}" validate_envoy_version_main(){ - echo "verify "main" GitHub branch has latest envoy version" # Get envoy version for current branch ENVOY_VERSIONS=$(sanitize_consul_envoy_version | awk '{print $2}' | tr ',' ' ') envoy_version_main_branch=$(get_major_version ${ENVOY_VERSIONS}) @@ -118,8 +122,8 @@ echo checking out branch: "${current_branch}" git checkout "${current_branch}" echo -echo "Branch ${current_branch} =>Consul version: ${CONSUL_VERSION}; Envoy Version: ${ENVOY_VERSIONS}" -echo "Branch ${GITHUB_DEFAULT_BRANCH} =>Consul version: ${CONSUL_VERSION_DEFAULT_BRANCH}; Envoy Version: ${ENVOY_VERSIONS_DEFAULT_BRANCH}" +echo "Branch ${current_branch} => Consul version: ${CONSUL_VERSION}; Envoy Version: ${ENVOY_VERSIONS}" +echo "Branch ${GITHUB_DEFAULT_BRANCH} => Consul version: ${CONSUL_VERSION_DEFAULT_BRANCH}; Envoy Version: ${ENVOY_VERSIONS_DEFAULT_BRANCH}" ## Get major Consul and Envoy versions on release and default branch MAJOR_CONSUL_VERSION=$(get_major_version ${CONSUL_VERSION}) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a6bade292ea6..cc2e2437a050 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,6 +28,8 @@ jobs: shared-ldflags: ${{ steps.shared-ldflags.outputs.shared-ldflags }} steps: - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + # action-set-product-version implicitly sets fields like 'product-version' using version/VERSION + # https://github.com/hashicorp/actions-set-product-version - name: set product version id: set-product-version uses: hashicorp/actions-set-product-version@v1 @@ -35,7 +37,6 @@ jobs: id: get-product-version run: | CONSUL_DATE=$(build-support/scripts/build-date.sh) - ## TODO: This assumes `make version` outputs 1.1.1+ent-prerel echo "product-date=${CONSUL_DATE}" >> "$GITHUB_OUTPUT" - name: Set shared -ldflags @@ -85,15 +86,15 @@ jobs: strategy: matrix: include: - - {go: "1.20.8", goos: "linux", goarch: "386"} - - {go: "1.20.8", goos: "linux", goarch: "amd64"} - - {go: "1.20.8", goos: "linux", goarch: "arm"} - - {go: "1.20.8", goos: "linux", goarch: "arm64"} - - {go: "1.20.8", goos: "freebsd", goarch: "386"} - - {go: "1.20.8", goos: "freebsd", goarch: "amd64"} - - {go: "1.20.8", goos: "windows", goarch: "386"} - - {go: "1.20.8", goos: "windows", goarch: "amd64"} - - {go: "1.20.8", goos: "solaris", goarch: "amd64"} + - {go: "1.20.10", goos: "linux", goarch: "386"} + - {go: "1.20.10", goos: "linux", goarch: "amd64"} + - {go: "1.20.10", goos: "linux", goarch: "arm"} + - {go: "1.20.10", goos: "linux", goarch: "arm64"} + - {go: "1.20.10", goos: "freebsd", goarch: "386"} + - {go: "1.20.10", goos: "freebsd", goarch: "amd64"} + - {go: "1.20.10", goos: "windows", goarch: "386"} + - {go: "1.20.10", goos: "windows", goarch: "amd64"} + - {go: "1.20.10", goos: "solaris", goarch: "amd64"} fail-fast: true name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build @@ -103,7 +104,7 @@ jobs: - name: Setup with node and yarn uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: '14' + node-version: '18' cache: 'yarn' cache-dependency-path: 'ui/yarn.lock' @@ -182,7 +183,7 @@ jobs: strategy: matrix: include: - - {go: "1.20.8", goos: "linux", goarch: "s390x"} + - {go: "1.20.10", goos: "linux", goarch: "s390x"} fail-fast: true name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build @@ -192,7 +193,7 @@ jobs: - name: Setup with node and yarn uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: '14' + node-version: '18' cache: 'yarn' cache-dependency-path: 'ui/yarn.lock' @@ -233,7 +234,7 @@ jobs: matrix: goos: [ darwin ] goarch: [ "amd64", "arm64" ] - go: [ "1.20.8" ] + go: [ "1.20.10" ] fail-fast: true name: Go ${{ matrix.go }} ${{ matrix.goos }} ${{ matrix.goarch }} build @@ -243,7 +244,7 @@ jobs: - name: Setup with node and yarn uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: '14' + node-version: '18' cache: 'yarn' cache-dependency-path: 'ui/yarn.lock' @@ -299,8 +300,10 @@ jobs: # This naming convention will be used ONLY for per-commit dev images - name: Set docker dev tag run: | - version="${{ env.version }}" - echo "dev_tag=${version%.*}-dev" >> $GITHUB_ENV + echo "full_dev_tag=${{ env.version }}" + echo "full_dev_tag=${{ env.version }}" >> $GITHUB_ENV + echo "minor_dev_tag=$(echo ${{ env.version }}| sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+(-[0-9a-zA-Z\+\.]+)?$/\1\2/')" + echo "minor_dev_tag=$(echo ${{ env.version }}| sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+(-[0-9a-zA-Z\+\.]+)?$/\1\2/')" >> $GITHUB_ENV - name: Docker Build (Action) uses: hashicorp/actions-docker-build@v1 @@ -312,8 +315,10 @@ jobs: docker.io/hashicorp/${{env.repo}}:${{env.version}} public.ecr.aws/hashicorp/${{env.repo}}:${{env.version}} dev_tags: | - docker.io/hashicorppreview/${{ env.repo }}:${{ env.dev_tag }} - docker.io/hashicorppreview/${{ env.repo }}:${{ env.dev_tag }}-${{ github.sha }} + docker.io/hashicorppreview/${{ env.repo }}:${{ env.full_dev_tag }} + docker.io/hashicorppreview/${{ env.repo }}:${{ env.full_dev_tag }}-${{ github.sha }} + docker.io/hashicorppreview/${{ env.repo }}:${{ env.minor_dev_tag }} + docker.io/hashicorppreview/${{ env.repo }}:${{ env.minor_dev_tag }}-${{ github.sha }} smoke_test: .github/scripts/verify_docker.sh v${{ env.version }} build-docker-ubi-redhat: @@ -353,8 +358,10 @@ jobs: # This naming convention will be used ONLY for per-commit dev images - name: Set docker dev tag run: | - version="${{ env.version }}" - echo "dev_tag=${version%.*}-dev" >> $GITHUB_ENV + echo "full_dev_tag=${{ env.version }}" + echo "full_dev_tag=${{ env.version }}" >> $GITHUB_ENV + echo "minor_dev_tag=$(echo ${{ env.version }}| sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+(-[0-9a-zA-Z\+\.]+)?$/\1\2/')" + echo "minor_dev_tag=$(echo ${{ env.version }}| sed -E 's/([0-9]+\.[0-9]+)\.[0-9]+(-[0-9a-zA-Z\+\.]+)?$/\1\2/')" >> $GITHUB_ENV - uses: hashicorp/actions-docker-build@v1 with: @@ -365,8 +372,10 @@ jobs: docker.io/hashicorp/${{env.repo}}:${{env.version}}-ubi public.ecr.aws/hashicorp/${{env.repo}}:${{env.version}}-ubi dev_tags: | - docker.io/hashicorppreview/${{ env.repo }}:${{ env.dev_tag }}-ubi - docker.io/hashicorppreview/${{ env.repo }}:${{ env.dev_tag }}-ubi-${{ github.sha }} + docker.io/hashicorppreview/${{ env.repo }}:${{ env.full_dev_tag }}-ubi + docker.io/hashicorppreview/${{ env.repo }}:${{ env.full_dev_tag }}-ubi-${{ github.sha }} + docker.io/hashicorppreview/${{ env.repo }}:${{ env.minor_dev_tag }}-ubi + docker.io/hashicorppreview/${{ env.repo }}:${{ env.minor_dev_tag }}-ubi-${{ github.sha }} smoke_test: .github/scripts/verify_docker.sh v${{ env.version }} verify-linux: diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index aede8a48e1b2..550fddd5d15f 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -37,10 +37,10 @@ jobs: - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: '16' + node-version: '18' - name: Install Yarn - run: npm install -g yarn + run: corepack enable # Install dependencies. - name: install yarn packages @@ -57,10 +57,10 @@ jobs: - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: '16' + node-version: '18' - name: Install Yarn - run: npm install -g yarn + run: corepack enable # Install dependencies. - name: install yarn packages @@ -86,10 +86,10 @@ jobs: - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: '16' + node-version: '18' - name: Install Yarn - run: npm install -g yarn + run: corepack enable - name: Install Chrome uses: browser-actions/setup-chrome@c485fa3bab6be59dce18dbc18ef6ab7cbc8ff5f1 # v1.2.0 diff --git a/.github/workflows/nightly-test-integrations-1.15.x.yml b/.github/workflows/nightly-test-integrations-1.15.x.yml index 80597f64e2fa..c570a541abd1 100644 --- a/.github/workflows/nightly-test-integrations-1.15.x.yml +++ b/.github/workflows/nightly-test-integrations-1.15.x.yml @@ -68,7 +68,7 @@ jobs: # 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.22.11", "1.23.12", "1.24.10", "1.25.9"] + # envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -102,7 +102,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.22.11", "1.23.12", "1.24.10", "1.25.9"] + envoy-version: ["1.22.11", "1.23.12", "1.24.12", "1.25.11"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations-1.16.x.yml b/.github/workflows/nightly-test-integrations-1.16.x.yml index c4f16d9be618..d9a771c3fe13 100644 --- a/.github/workflows/nightly-test-integrations-1.16.x.yml +++ b/.github/workflows/nightly-test-integrations-1.16.x.yml @@ -68,7 +68,7 @@ jobs: # 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.10", "1.25.9", "1.26.4", "1.27.0"] + # envoy-version: ["1.23.12", "1.24.12", "1.25.11", "1.26.6"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -102,7 +102,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.23.12", "1.24.10", "1.25.9", "1.26.4"] + envoy-version: ["1.23.12", "1.24.12", "1.25.11", "1.26.6"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: diff --git a/.github/workflows/nightly-test-integrations.yml b/.github/workflows/nightly-test-integrations.yml index 5e30df72229e..7fa1ec1f48da 100644 --- a/.github/workflows/nightly-test-integrations.yml +++ b/.github/workflows/nightly-test-integrations.yml @@ -65,7 +65,7 @@ jobs: # 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.10", "1.25.9", "1.26.4", "1.27.0"] + # 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)]' @@ -99,7 +99,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.24.10", "1.25.9", "1.26.4", "1.27.0"] + 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: diff --git a/.github/workflows/nightly-test-main.yaml b/.github/workflows/nightly-test-main.yaml index 2846f5b71c39..a089121cc8c6 100644 --- a/.github/workflows/nightly-test-main.yaml +++ b/.github/workflows/nightly-test-main.yaml @@ -24,7 +24,7 @@ jobs: # Not necessary to use yarn, but enables caching - uses: actions/setup-node@e33196f7422957bea03ed53f6fbb155025ffc7b8 # v3.7.0 with: - node-version: 14 + node-version: 18 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: 14 + node-version: 18 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: 14 + node-version: 18 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: 14 + node-version: 18 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: 14 + node-version: 18 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: 14 + node-version: 18 cache: 'yarn' cache-dependency-path: ./ui/yarn.lock diff --git a/.github/workflows/test-integrations-windows.yml b/.github/workflows/test-integrations-windows.yml index 8ece1ef6c9b7..16f7b26fdc67 100644 --- a/.github/workflows/test-integrations-windows.yml +++ b/.github/workflows/test-integrations-windows.yml @@ -54,7 +54,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: [ "1.27.0" ] + envoy-version: [ "1.27.2" ] xds-target: [ "server", "client" ] env: ENVOY_VERSION: ${{ matrix.envoy-version }} diff --git a/.github/workflows/test-integrations.yml b/.github/workflows/test-integrations.yml index 28dcf701fdf1..cbda50b0e5da 100644 --- a/.github/workflows/test-integrations.yml +++ b/.github/workflows/test-integrations.yml @@ -80,7 +80,8 @@ jobs: contents: read strategy: matrix: - nomad-version: ['v1.6.1', 'v1.5.8', 'v1.4.12'] + nomad-version: ['v1.6.2', 'v1.5.9', 'v1.4.13'] + steps: - name: Checkout Nomad uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 @@ -159,7 +160,7 @@ jobs: contents: read strategy: matrix: - vault-version: ["1.14.1", "1.13.5", "1.12.9", "1.11.12"] + vault-version: ["1.15.0", "1.14.4", "1.13.8", "1.12.11"] env: VAULT_BINARY_VERSION: ${{ matrix.vault-version }} steps: @@ -259,8 +260,8 @@ jobs: 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.10", "1.25.9", "1.26.4", "1.27.0"] + # multiplied by 2 based on these values: + # envoy-version: ["1.27.2"] # xds-target: ["server", "client"] TOTAL_RUNNERS: 4 JQ_SLICER: '[ inputs ] | [_nwise(length / $runnercount | floor)]' @@ -294,7 +295,7 @@ jobs: strategy: fail-fast: false matrix: - envoy-version: ["1.27.0"] + envoy-version: ["1.27.2"] xds-target: ["server", "client"] test-cases: ${{ fromJSON(needs.generate-envoy-job-matrices.outputs.envoy-matrix) }} env: @@ -487,6 +488,88 @@ jobs: DD_ENV: ci run: datadog-ci junit upload --service "$GITHUB_REPOSITORY" $TEST_RESULTS_DIR/results.xml + integration-test-with-deployer: + runs-on: ${{ fromJSON(needs.setup.outputs.compute-large ) }} + needs: + - setup + permissions: + id-token: write # NOTE: this permission is explicitly required for Vault auth. + contents: read + strategy: + fail-fast: false + env: + DEPLOYER_CONSUL_DATAPLANE_IMAGE: "docker.mirror.hashicorp.services/hashicorppreview/consul-dataplane:1.3-dev" + steps: + - name: Checkout code + uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + # 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 + - name: Build image + run: make test-compat-integ-setup + - name: Integration Tests + run: | + mkdir -p "${{ env.TEST_RESULTS_DIR }}" + export NOLOGBUFFER=1 + cd ./test-integ + go run gotest.tools/gotestsum@v${{env.GOTESTSUM_VERSION}} \ + --raw-command \ + --format=standard-verbose \ + --debug \ + -- \ + go test \ + -tags "${{ env.GOTAGS }}" \ + -timeout=20m \ + -parallel=2 \ + -json \ + `go list -tags "${{ env.GOTAGS }}" ./... | grep -v peering_commontopo` \ + --target-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ + --target-version local \ + --latest-image ${{ env.CONSUL_LATEST_IMAGE_NAME }} \ + --latest-version latest + 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: @@ -498,6 +581,7 @@ jobs: - generate-envoy-job-matrices - envoy-integration-test - compatibility-integration-test + - integration-test-with-deployer runs-on: ${{ fromJSON(needs.setup.outputs.compute-small) }} if: always() && needs.conditional-skip.outputs.skip-ci != 'true' steps: diff --git a/.github/workflows/verify-envoy-version.yml b/.github/workflows/verify-envoy-version.yml index 9e8b7e7e89b3..003888eddf6e 100644 --- a/.github/workflows/verify-envoy-version.yml +++ b/.github/workflows/verify-envoy-version.yml @@ -14,6 +14,9 @@ on: - main - release/** +env: + SKIP_VERIFY_ENVOY_VERSION: ${{ vars.SKIP_VERIFY_ENVOY_VERSION }} + jobs: verify-envoy-version: runs-on: ubuntu-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index f72f27cb912d..8bbe1143e7f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,166 @@ +## 1.17.0 (October 31, 2023) + +BREAKING CHANGES: + +* api: RaftLeaderTransfer now requires an id string. An empty string can be specified to keep the old behavior. [[GH-17107](https://github.com/hashicorp/consul/issues/17107)] +* audit-logging: **(Enterprise only)** allowing timestamp based filename only on rotation. initially the filename will be just file.json [[GH-18668](https://github.com/hashicorp/consul/issues/18668)] + +SECURITY: + +* Update `golang.org/x/net` to v0.17.0 to address [CVE-2023-39325](https://nvd.nist.gov/vuln/detail/CVE-2023-39325) +/ [CVE-2023-44487](https://nvd.nist.gov/vuln/detail/CVE-2023-44487)(`x/net/http2`). [[GH-19225](https://github.com/hashicorp/consul/issues/19225)] +* Upgrade Go to 1.20.10. +This resolves vulnerability [CVE-2023-39325](https://nvd.nist.gov/vuln/detail/CVE-2023-39325) +/ [CVE-2023-44487](https://nvd.nist.gov/vuln/detail/CVE-2023-44487)(`net/http`). [[GH-19225](https://github.com/hashicorp/consul/issues/19225)] +* Upgrade `google.golang.org/grpc` to 1.56.3. +This resolves vulnerability [CVE-2023-44487](https://nvd.nist.gov/vuln/detail/CVE-2023-44487). [[GH-19414](https://github.com/hashicorp/consul/issues/19414)] +* connect: update supported envoy versions to 1.24.12, 1.25.11, 1.26.6, 1.27.2 to address [CVE-2023-44487](https://github.com/envoyproxy/envoy/security/advisories/GHSA-jhv4-f7mr-xx76) [[GH-19275](https://github.com/hashicorp/consul/issues/19275)] + +FEATURE PREVIEW: **Catalog v2** + +This release provides the ability to preview Consul's v2 Catalog and Resource API if enabled. The new model supports +multi-port application deployments with only a single Envoy proxy. Note that the v1 and v2 catalogs are not cross +compatible, and not all Consul features are available within this v2 feature preview. See the [v2 Catalog and Resource +API documentation](https://developer.hashicorp.com/consul/docs/architecture/v2) for more information. The v2 Catalog and +Resources API should be considered a feature preview within this release and should not be used in production +environments. + +Limitations +* The v2 catalog API feature preview does not support connections with client agents. As a result, 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. +* HCP Consul does not support multi-port services or the v2 catalog API in this release. + +Significant Pull Requests +* [[Catalog resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/catalog/internal/controllers) +* [[Mesh resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/mesh/internal/controllers) +* [[Auth resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/auth/internal) +* [[V2 Protobufs]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/proto-public) + +FEATURES: + +* Support custom watches on the Consul Controller framework. [[GH-18439](https://github.com/hashicorp/consul/issues/18439)] +* Windows: support consul connect envoy command on Windows [[GH-17694](https://github.com/hashicorp/consul/issues/17694)] +* acl: Add BindRule support for templated policies. Add new BindType: templated-policy and BindVar field for templated policy variables. [[GH-18719](https://github.com/hashicorp/consul/issues/18719)] +* acl: Add new `acl.tokens.dns` config field which specifies the token used implicitly during dns checks. [[GH-17936](https://github.com/hashicorp/consul/issues/17936)] +* acl: Added ACL Templated policies to simplify getting the right ACL token. [[GH-18708](https://github.com/hashicorp/consul/issues/18708)] +* acl: Adds a new ACL rule for workload identities [[GH-18769](https://github.com/hashicorp/consul/issues/18769)] +* acl: Adds workload identity templated policy [[GH-19077](https://github.com/hashicorp/consul/issues/19077)] +* api-gateway: Add support for response header modifiers on http-route configuration entry [[GH-18646](https://github.com/hashicorp/consul/issues/18646)] +* api-gateway: add retry and timeout filters [[GH-18324](https://github.com/hashicorp/consul/issues/18324)] +* cli: Add `bind-var` flag to `consul acl binding-rule` for templated policy variables. [[GH-18719](https://github.com/hashicorp/consul/issues/18719)] +* cli: Add `consul acl templated-policy` commands to read, list and preview templated policies. [[GH-18816](https://github.com/hashicorp/consul/issues/18816)] +* config-entry(api-gateway): (Enterprise only) Add GatewayPolicy to APIGateway Config Entry listeners +* config-entry(api-gateway): (Enterprise only) Add JWTFilter to HTTPRoute Filters +* dataplane: Allow getting bootstrap parameters when using V2 APIs [[GH-18504](https://github.com/hashicorp/consul/issues/18504)] +* gateway: **(Enterprise only)** Add JWT authentication and authorization to APIGateway Listeners and HTTPRoutes. +* mesh: **(Enterprise only)** Adds rate limiting config to service-defaults [[GH-18583](https://github.com/hashicorp/consul/issues/18583)] +* xds: Add a built-in Envoy extension that appends OpenTelemetry Access Logging (otel-access-logging) to the HTTP Connection Manager filter. [[GH-18336](https://github.com/hashicorp/consul/issues/18336)] +* xds: Add support for patching outbound listeners to the built-in Envoy External Authorization extension. [[GH-18336](https://github.com/hashicorp/consul/issues/18336)] + +IMPROVEMENTS: + +* raft: upgrade raft-wal library version to 0.4.1. [[GH-19314](https://github.com/hashicorp/consul/issues/19314)] +* xds: Use downstream protocol when connecting to local app [[GH-18573](https://github.com/hashicorp/consul/issues/18573)] +* Windows: Integration tests for Consul Windows VMs [[GH-18007](https://github.com/hashicorp/consul/issues/18007)] +* acl: Use templated policy to generate synthetic policies for tokens/roles with node and/or service identities [[GH-18813](https://github.com/hashicorp/consul/issues/18813)] +* api: added `CheckRegisterOpts` to Agent API [[GH-18943](https://github.com/hashicorp/consul/issues/18943)] +* api: added `Token` field to `ServiceRegisterOpts` type in Agent API [[GH-18983](https://github.com/hashicorp/consul/issues/18983)] +* ca: Vault CA provider config no longer requires root_pki_path for secondary datacenters [[GH-17831](https://github.com/hashicorp/consul/issues/17831)] +* cli: Added `-templated-policy`, `-templated-policy-file`, `-replace-templated-policy`, `-append-templated-policy`, `-replace-templated-policy-file`, `-append-templated-policy-file` and `-var` flags for creating or updating tokens/roles. [[GH-18708](https://github.com/hashicorp/consul/issues/18708)] +* config: Add new `tls.defaults.verify_server_hostname` configuration option. This specifies the default value for any interfaces that support the `verify_server_hostname` option. [[GH-17155](https://github.com/hashicorp/consul/issues/17155)] +* connect: update supported envoy versions to 1.24.10, 1.25.9, 1.26.4, 1.27.0 [[GH-18300](https://github.com/hashicorp/consul/issues/18300)] +* ui: Use Community verbiage [[GH-18560](https://github.com/hashicorp/consul/issues/18560)] + +BUG FIXES: + +* api: add custom marshal/unmarshal for ServiceResolverConfigEntry.RequestTimeout so config entries that set this field can be read using the API. [[GH-19031](https://github.com/hashicorp/consul/issues/19031)] +* ca: ensure Vault CA provider respects Vault Enterprise namespace configuration. [[GH-19095](https://github.com/hashicorp/consul/issues/19095)] +* catalog api: fixes a bug with catalog api where filter query parameter was not working correctly for the `/v1/catalog/services` endpoint [[GH-18322](https://github.com/hashicorp/consul/issues/18322)] +* connect: **(Enterprise only)** Fix bug where incorrect service-defaults entries were fetched to determine an upstream's protocol whenever the upstream did not explicitly define the namespace / partition. When this bug occurs, upstreams would use the protocol from a service-default entry in the default namespace / partition, rather than their own namespace / partition. +* connect: Fix bug where uncleanly closed xDS connections would influence connection balancing for too long and prevent envoy instances from starting. Two new configuration fields +`performance.grpc_keepalive_timeout` and `performance.grpc_keepalive_interval` now exist to allow for configuration on how often these dead connections will be cleaned up. [[GH-19339](https://github.com/hashicorp/consul/issues/19339)] +* dev-mode: Fix dev mode has new line in responses. Now new line is added only when url has pretty query parameter. [[GH-18367](https://github.com/hashicorp/consul/issues/18367)] +* dns: **(Enterprise only)** Fix bug where sameness group queries did not correctly inherit the agent's partition. +* docs: fix list of telemetry metrics [[GH-17593](https://github.com/hashicorp/consul/issues/17593)] +* gateways: Fix a bug where a service in a peered datacenter could not access an external node service through a terminating gateway [[GH-18959](https://github.com/hashicorp/consul/issues/18959)] +* server: **(Enterprise Only)** Fixed an issue where snake case keys were rejected when configuring the control-plane-request-limit config entry +* telemetry: emit consul version metric on a regular interval. [[GH-6876](https://github.com/hashicorp/consul/issues/6876)] +* tlsutil: Default setting of ServerName field in outgoing TLS configuration for checks now handled by crypto/tls. [[GH-17481](https://github.com/hashicorp/consul/issues/17481)] + +## 1.17.0-rc1 (October 11, 2023) + +BREAKING CHANGES: + +* api: RaftLeaderTransfer now requires an id string. An empty string can be specified to keep the old behavior. [[GH-17107](https://github.com/hashicorp/consul/issues/17107)] +* audit-logging: **(Enterprise only)** allowing timestamp based filename only on rotation. initially the filename will be just file.json [[GH-18668](https://github.com/hashicorp/consul/issues/18668)] + +FEATURE PREVIEW: **Catalog v2** + +This release provides the ability to preview Consul's v2 Catalog and Resource API if enabled. The new model supports +multi-port application deployments with only a single Envoy proxy. Note that the v1 and v2 catalogs are not cross +compatible, and not all Consul features are available within this v2 feature preview. See the [v2 Catalog and Resource +API documentation](https://developer.hashicorp.com/consul/docs/architecture/v2) for more information. The v2 Catalog and +Resources API should be considered a feature preview within this release and should not be used in production +environments. + +Limitations +* The v2 catalog API feature preview does not support connections with client agents. As a result, 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. +* HCP Consul does not support multi-port services or the v2 catalog API in this release. +* The v2 API only supports transparent proxy mode where services that have permissions to connect to each other can use + Kube DNS to connect. + +Known Issues +* When using the v2 API with transparent proxy, Kubernetes pods cannot use L7 liveness, readiness, or startup probes. + +Significant Pull Requests +* [[Catalog resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/catalog/internal/controllers) +* [[Mesh resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/mesh/internal/controllers) +* [[Auth resource controllers]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/internal/auth/internal) +* [[V2 Protobufs]](https://github.com/hashicorp/consul/tree/e6b724d06249d3e62cd75afe3ee6042ba1fd5415/proto-public) + +FEATURES: + +* Support custom watches on the Consul Controller framework. [[GH-18439](https://github.com/hashicorp/consul/issues/18439)] +* Windows: support consul connect envoy command on Windows [[GH-17694](https://github.com/hashicorp/consul/issues/17694)] +* acl: Add BindRule support for templated policies. Add new BindType: templated-policy and BindVar field for templated policy variables. [[GH-18719](https://github.com/hashicorp/consul/issues/18719)] +* acl: Add new `acl.tokens.dns` config field which specifies the token used implicitly during dns checks. [[GH-17936](https://github.com/hashicorp/consul/issues/17936)] +* acl: Added ACL Templated policies to simplify getting the right ACL token. [[GH-18708](https://github.com/hashicorp/consul/issues/18708)] +* acl: Adds a new ACL rule for workload identities [[GH-18769](https://github.com/hashicorp/consul/issues/18769)] +* api-gateway: Add support for response header modifiers on http-route configuration entry [[GH-18646](https://github.com/hashicorp/consul/issues/18646)] +* api-gateway: add retry and timeout filters [[GH-18324](https://github.com/hashicorp/consul/issues/18324)] +* cli: Add `bind-var` flag to `consul acl binding-rule` for templated policy variables. [[GH-18719](https://github.com/hashicorp/consul/issues/18719)] +* cli: Add `consul acl templated-policy` commands to read, list and preview templated policies. [[GH-18816](https://github.com/hashicorp/consul/issues/18816)] +* config-entry(api-gateway): (Enterprise only) Add GatewayPolicy to APIGateway Config Entry listeners +* config-entry(api-gateway): (Enterprise only) Add JWTFilter to HTTPRoute Filters +* dataplane: Allow getting bootstrap parameters when using V2 APIs [[GH-18504](https://github.com/hashicorp/consul/issues/18504)] +* gateway: **(Enterprise only)** Add JWT authentication and authorization to APIGateway Listeners and HTTPRoutes. +* mesh: **(Enterprise only)** Adds rate limiting config to service-defaults [[GH-18583](https://github.com/hashicorp/consul/issues/18583)] +* xds: Add a built-in Envoy extension that appends OpenTelemetry Access Logging (otel-access-logging) to the HTTP Connection Manager filter. [[GH-18336](https://github.com/hashicorp/consul/issues/18336)] +* xds: Add support for patching outbound listeners to the built-in Envoy External Authorization extension. [[GH-18336](https://github.com/hashicorp/consul/issues/18336)] + +IMPROVEMENTS: + +* xds: Use downstream protocol when connecting to local app [[GH-18573](https://github.com/hashicorp/consul/issues/18573)] +* Windows: Integration tests for Consul Windows VMs [[GH-18007](https://github.com/hashicorp/consul/issues/18007)] +* acl: Use templated policy to generate synthetic policies for tokens/roles with node and/or service identities [[GH-18813](https://github.com/hashicorp/consul/issues/18813)] +* api: added `CheckRegisterOpts` to Agent API [[GH-18943](https://github.com/hashicorp/consul/issues/18943)] +* api: added `Token` field to `ServiceRegisterOpts` type in Agent API [[GH-18983](https://github.com/hashicorp/consul/issues/18983)] +* ca: Vault CA provider config no longer requires root_pki_path for secondary datacenters [[GH-17831](https://github.com/hashicorp/consul/issues/17831)] +* cli: Added `-templated-policy`, `-templated-policy-file`, `-replace-templated-policy`, `-append-templated-policy`, `-replace-templated-policy-file`, `-append-templated-policy-file` and `-var` flags for creating or updating tokens/roles. [[GH-18708](https://github.com/hashicorp/consul/issues/18708)] +* config: Add new `tls.defaults.verify_server_hostname` configuration option. This specifies the default value for any interfaces that support the `verify_server_hostname` option. [[GH-17155](https://github.com/hashicorp/consul/issues/17155)] +* connect: update supported envoy versions to 1.24.10, 1.25.9, 1.26.4, 1.27.0 [[GH-18300](https://github.com/hashicorp/consul/issues/18300)] +* ui: Use Community verbiage [[GH-18560](https://github.com/hashicorp/consul/issues/18560)] + +BUG FIXES: + +* api: add custom marshal/unmarshal for ServiceResolverConfigEntry.RequestTimeout so config entries that set this field can be read using the API. [[GH-19031](https://github.com/hashicorp/consul/issues/19031)] +* dev-mode: Fix dev mode has new line in responses. Now new line is added only when url has pretty query parameter. [[GH-18367](https://github.com/hashicorp/consul/issues/18367)] +* telemetry: emit consul version metric on a regular interval. [[GH-6876](https://github.com/hashicorp/consul/issues/6876)] +* tlsutil: Default setting of ServerName field in outgoing TLS configuration for checks now handled by crypto/tls. [[GH-17481](https://github.com/hashicorp/consul/issues/17481)] + ## 1.16.2 (September 19, 2023) SECURITY: diff --git a/Makefile b/Makefile index 4ee07faef500..a7c275511c51 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ MOCKERY_VERSION='v2.20.0' BUF_VERSION='v1.26.0' PROTOC_GEN_GO_GRPC_VERSION="v1.2.0" -MOG_VERSION='v0.4.0' +MOG_VERSION='v0.4.1' PROTOC_GO_INJECT_TAG_VERSION='v1.3.0' PROTOC_GEN_GO_BINARY_VERSION="v0.1.0" DEEP_COPY_VERSION='bc3f5aa5735d8a54961580a3a24422c308c831c2' @@ -438,6 +438,9 @@ codegen: codegen-tools ## Deep copy @$(SHELL) $(CURDIR)/agent/consul/state/deep-copy.sh @$(SHELL) $(CURDIR)/agent/config/deep-copy.sh copywrite headers + # Special case for MPL headers in /api and /sdk + cd api && $(CURDIR)/build-support/scripts/copywrite-exceptions.sh + cd sdk && $(CURDIR)/build-support/scripts/copywrite-exceptions.sh print-% : ; @echo $($*) ## utility to echo a makefile variable (i.e. 'make print-GOPATH') diff --git a/NOTICE.md b/NOTICE.md deleted file mode 100644 index fe34b5e57155..000000000000 --- a/NOTICE.md +++ /dev/null @@ -1,3 +0,0 @@ -Copyright © 2014-2018 HashiCorp, Inc. - -This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this project, you can obtain one at http://mozilla.org/MPL/2.0/. diff --git a/acl/MockAuthorizer.go b/acl/MockAuthorizer.go index 46e6c243a634..9941f81e3f05 100644 --- a/acl/MockAuthorizer.go +++ b/acl/MockAuthorizer.go @@ -224,6 +224,11 @@ func (m *MockAuthorizer) ServiceReadAll(ctx *AuthorizerContext) EnforcementDecis return ret.Get(0).(EnforcementDecision) } +func (m *MockAuthorizer) ServiceReadPrefix(prefix string, ctx *AuthorizerContext) EnforcementDecision { + ret := m.Called(ctx) + return ret.Get(0).(EnforcementDecision) +} + // ServiceWrite checks for permission to create or update a given // service func (m *MockAuthorizer) ServiceWrite(segment string, ctx *AuthorizerContext) EnforcementDecision { diff --git a/acl/acl_test.go b/acl/acl_test.go index 17547b4959d1..28542024e956 100644 --- a/acl/acl_test.go +++ b/acl/acl_test.go @@ -300,6 +300,14 @@ func checkDenyServiceReadAll(t *testing.T, authz Authorizer, _ string, entCtx *A require.Equal(t, Deny, authz.ServiceReadAll(entCtx)) } +func checkAllowServiceReadPrefix(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { + require.Equal(t, Allow, authz.ServiceReadPrefix(prefix, entCtx)) +} + +func checkDenyServiceReadPrefix(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { + require.Equal(t, Deny, authz.ServiceReadPrefix(prefix, entCtx)) +} + func checkDenyServiceWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Deny, authz.ServiceWrite(prefix, entCtx)) } @@ -456,6 +464,10 @@ func checkDefaultServiceReadAll(t *testing.T, authz Authorizer, _ string, entCtx require.Equal(t, Default, authz.ServiceReadAll(entCtx)) } +func checkDefaultServiceReadPrefix(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { + require.Equal(t, Default, authz.ServiceReadPrefix(prefix, entCtx)) +} + func checkDefaultServiceWrite(t *testing.T, authz Authorizer, prefix string, entCtx *AuthorizerContext) { require.Equal(t, Default, authz.ServiceWrite(prefix, entCtx)) } diff --git a/acl/authorizer.go b/acl/authorizer.go index 9abd09b02f79..9e5bacc25e86 100644 --- a/acl/authorizer.go +++ b/acl/authorizer.go @@ -171,6 +171,9 @@ type Authorizer interface { // ServiceReadAll checks for permission to read all services ServiceReadAll(*AuthorizerContext) EnforcementDecision + // ServiceReadPrefix checks for permission to read services within the given prefix. + ServiceReadPrefix(string, *AuthorizerContext) EnforcementDecision + // ServiceWrite checks for permission to create or update a given // service ServiceWrite(string, *AuthorizerContext) EnforcementDecision @@ -507,6 +510,14 @@ func (a AllowAuthorizer) ServiceReadAllAllowed(ctx *AuthorizerContext) error { return nil } +// ServiceReadPrefixAllowed checks for permission to read services within the given prefix +func (a AllowAuthorizer) ServiceReadPrefixAllowed(prefix string, ctx *AuthorizerContext) error { + if a.Authorizer.ServiceReadPrefix(prefix, ctx) != Allow { + return PermissionDeniedByACL(a, ctx, ResourceService, AccessRead, prefix) // read + } + return nil +} + // ServiceWriteAllowed checks for permission to create or update a given // service func (a AllowAuthorizer) ServiceWriteAllowed(name string, ctx *AuthorizerContext) error { diff --git a/acl/chained_authorizer.go b/acl/chained_authorizer.go index e35b62ad2fbb..76e973d2e9ed 100644 --- a/acl/chained_authorizer.go +++ b/acl/chained_authorizer.go @@ -275,6 +275,12 @@ func (c *ChainedAuthorizer) ServiceReadAll(entCtx *AuthorizerContext) Enforcemen }) } +func (c *ChainedAuthorizer) ServiceReadPrefix(prefix string, entCtx *AuthorizerContext) EnforcementDecision { + return c.executeChain(func(authz Authorizer) EnforcementDecision { + return authz.ServiceReadPrefix(prefix, entCtx) + }) +} + // ServiceWrite checks for permission to create or update a given // service func (c *ChainedAuthorizer) ServiceWrite(name string, entCtx *AuthorizerContext) EnforcementDecision { diff --git a/acl/chained_authorizer_test.go b/acl/chained_authorizer_test.go index 6c6152dded13..01d33a029204 100644 --- a/acl/chained_authorizer_test.go +++ b/acl/chained_authorizer_test.go @@ -107,6 +107,9 @@ func (authz testAuthorizer) ServiceRead(string, *AuthorizerContext) EnforcementD func (authz testAuthorizer) ServiceReadAll(*AuthorizerContext) EnforcementDecision { return EnforcementDecision(authz) } +func (authz testAuthorizer) ServiceReadPrefix(string, *AuthorizerContext) EnforcementDecision { + return EnforcementDecision(authz) +} func (authz testAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision { return EnforcementDecision(authz) } diff --git a/acl/policy_authorizer.go b/acl/policy_authorizer.go index 802b49a8d98f..11d19609efde 100644 --- a/acl/policy_authorizer.go +++ b/acl/policy_authorizer.go @@ -712,7 +712,7 @@ func (p *policyAuthorizer) KeyWritePrefix(prefix string, _ *AuthorizerContext) E // that do NOT grant AccessWrite. // // Conditions for Default: - // * There is no prefix match rule that would appy to the given prefix. + // * There is no prefix match rule that would apply to the given prefix. // AND // * There are no rules (exact or prefix match) within/under the given prefix // that would NOT grant AccessWrite. @@ -916,6 +916,62 @@ func (p *policyAuthorizer) ServiceReadAll(_ *AuthorizerContext) EnforcementDecis return p.allAllowed(p.serviceRules, AccessRead) } +// ServiceReadPrefix determines whether service read is allowed within the given prefix. +// +// Access is allowed iff all the following are true: +// - There's a read policy for the longest prefix that's shorter or equal to the provided prefix. +// - There's no deny policy for any prefix that's longer than the given prefix. +// - There's no deny policy for any exact match that's within the given prefix. +func (p *policyAuthorizer) ServiceReadPrefix(prefix string, _ *AuthorizerContext) EnforcementDecision { + access := Default + + // 1. Walk the prefix tree from root to the given prefix. Find the longest prefix matching ours, + // and use that policy to determine our access as that is the most specific prefix, and it + // should take precedence. + p.serviceRules.WalkPath(prefix, func(path string, leaf interface{}) bool { + rule := leaf.(*policyAuthorizerRadixLeaf) + + if rule.prefix != nil { + switch rule.prefix.access { + case AccessRead, AccessWrite: + access = Allow + default: + access = Deny + } + } + + // Don't stop iteration because we want to visit all nodes down to our leaf to find the more specific match + // as it should take precedence. + return false + }) + + // 2. Check rules "below" the given prefix. Access is allowed if there's no deny policy + // for any prefix longer than ours or for any exact match that's within the prefix. + p.serviceRules.WalkPrefix(prefix, func(path string, leaf interface{}) bool { + rule := leaf.(*policyAuthorizerRadixLeaf) + + if rule.prefix != nil && (rule.prefix.access != AccessRead && rule.prefix.access != AccessWrite) { + // If any prefix longer than the provided prefix has "deny" policy, then access is denied. + access = Deny + + // We don't need to look at the rest of the tree in this case, so terminate early. + return true + } + + if rule.exact != nil && (rule.exact.access != AccessRead && rule.exact.access != AccessWrite) { + // If any exact match policy has an explicit deny, then access is denied. + access = Deny + + // We don't need to look at the rest of the tree in this case, so terminate early. + return true + } + + return false + }) + + return access +} + // ServiceWrite checks if writing (registering) a service is allowed func (p *policyAuthorizer) ServiceWrite(name string, _ *AuthorizerContext) EnforcementDecision { if rule, ok := getPolicy(name, p.serviceRules); ok { diff --git a/acl/policy_authorizer_test.go b/acl/policy_authorizer_test.go index 06e5ee2bb25e..96272d8b12f4 100644 --- a/acl/policy_authorizer_test.go +++ b/acl/policy_authorizer_test.go @@ -64,6 +64,8 @@ func TestPolicyAuthorizer(t *testing.T) { {name: "DefaultPreparedQueryRead", prefix: "foo", check: checkDefaultPreparedQueryRead}, {name: "DefaultPreparedQueryWrite", prefix: "foo", check: checkDefaultPreparedQueryWrite}, {name: "DefaultServiceRead", prefix: "foo", check: checkDefaultServiceRead}, + {name: "DefaultServiceReadAll", prefix: "foo", check: checkDefaultServiceReadAll}, + {name: "DefaultServiceReadPrefix", prefix: "foo", check: checkDefaultServiceReadPrefix}, {name: "DefaultServiceWrite", prefix: "foo", check: checkDefaultServiceWrite}, {name: "DefaultServiceWriteAny", prefix: "", check: checkDefaultServiceWriteAny}, {name: "DefaultSessionRead", prefix: "foo", check: checkDefaultSessionRead}, @@ -396,6 +398,7 @@ func TestPolicyAuthorizer(t *testing.T) { {name: "ServiceReadDenied", prefix: "football", check: checkDenyServiceRead}, {name: "ServiceWriteDenied", prefix: "football", check: checkDenyServiceWrite}, {name: "ServiceWriteAnyAllowed", prefix: "", check: checkAllowServiceWriteAny}, + {name: "ServiceReadWithinPrefixDenied", prefix: "foot", check: checkDenyServiceReadPrefix}, {name: "IdentityReadPrefixAllowed", prefix: "fo", check: checkAllowIdentityRead}, {name: "IdentityWritePrefixDenied", prefix: "fo", check: checkDenyIdentityWrite}, @@ -570,6 +573,214 @@ func TestPolicyAuthorizer(t *testing.T) { {name: "AllDenied", prefix: "*", check: checkDenyIntentionWrite}, }, }, + "Service Read Prefix - read allowed with write policy and exact prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo", + Policy: PolicyWrite, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixAllowed", prefix: "foo", check: checkAllowServiceReadPrefix}, + }, + }, + "Service Read Prefix - read allowed with read policy and exact prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo", + Policy: PolicyRead, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixAllowed", prefix: "foo", check: checkAllowServiceReadPrefix}, + }, + }, + "Service Read Prefix - read denied with deny policy and exact prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo", + Policy: PolicyDeny, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, + }, + }, + "Service Read Prefix - read allowed with write policy and shorter prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo", + Policy: PolicyWrite, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixAllowed", prefix: "foo1", check: checkAllowServiceReadPrefix}, + }, + }, + "Service Read Prefix - read allowed with read policy and shorter prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo", + Policy: PolicyRead, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixAllowed", prefix: "foo1", check: checkAllowServiceReadPrefix}, + }, + }, + "Service Read Prefix - read denied with deny policy and shorter prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo", + Policy: PolicyDeny, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixDenied", prefix: "foo1", check: checkDenyServiceReadPrefix}, + }, + }, + "Service Read Prefix - default with write policy and longer prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo1", + Policy: PolicyWrite, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixDefault", prefix: "foo", check: checkDefaultServiceReadPrefix}, + }, + }, + "Service Read Prefix - default with read policy and longer prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo1", + Policy: PolicyRead, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixDefault", prefix: "foo", check: checkDefaultServiceReadPrefix}, + }, + }, + "Service Read Prefix - deny with deny policy and longer prefix": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "foo1", + Policy: PolicyDeny, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, + }, + }, + "Service Read Prefix - allow with two shorter prefixes - more specific one allowing read and less specific denying": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "fo", + Policy: PolicyDeny, + }, + { + Name: "foo", + Policy: PolicyRead, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixAllowed", prefix: "foo", check: checkAllowServiceReadPrefix}, + }, + }, + "Service Read Prefix - deny with two shorter prefixes - more specific one denying and less specific allowing read": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "fo", + Policy: PolicyRead, + }, + { + Name: "foo", + Policy: PolicyDeny, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, + }, + }, + "Service Read Prefix - deny with exact match denying": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "fo", + Policy: PolicyRead, + }, + }, + Services: []*ServiceRule{ + { + Name: "foo-123", + Policy: PolicyDeny, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, + }, + }, + "Service Read Prefix - allow with exact match allowing read": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "fo", + Policy: PolicyRead, + }, + }, + Services: []*ServiceRule{ + { + Name: "foo-123", + Policy: PolicyRead, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixAllowed", prefix: "foo", check: checkAllowServiceReadPrefix}, + }, + }, + "Service Read Prefix - deny with exact match allowing read but prefix match denying": { + policy: &Policy{PolicyRules: PolicyRules{ + ServicePrefixes: []*ServiceRule{ + { + Name: "fo", + Policy: PolicyDeny, + }, + }, + Services: []*ServiceRule{ + { + Name: "foo-123", + Policy: PolicyRead, + }, + }, + }}, + checks: []aclCheck{ + {name: "ServiceReadPrefixDenied", prefix: "foo", check: checkDenyServiceReadPrefix}, + }, + }, } for name, tcase := range cases { diff --git a/acl/static_authorizer.go b/acl/static_authorizer.go index 225aa64e74db..759b378669ad 100644 --- a/acl/static_authorizer.go +++ b/acl/static_authorizer.go @@ -257,6 +257,13 @@ func (s *staticAuthorizer) ServiceReadAll(*AuthorizerContext) EnforcementDecisio return Deny } +func (s *staticAuthorizer) ServiceReadPrefix(string, *AuthorizerContext) EnforcementDecision { + if s.defaultAllow { + return Allow + } + return Deny +} + func (s *staticAuthorizer) ServiceWrite(string, *AuthorizerContext) EnforcementDecision { if s.defaultAllow { return Allow diff --git a/agent/agent.go b/agent/agent.go index 06f538bf9695..dca7bf948739 100644 --- a/agent/agent.go +++ b/agent/agent.go @@ -34,6 +34,7 @@ import ( "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "google.golang.org/grpc" + "google.golang.org/grpc/keepalive" "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/acl/resolver" @@ -655,43 +656,12 @@ func (a *Agent) Start(ctx context.Context) error { return fmt.Errorf("failed to start Consul enterprise component: %v", err) } - // Create proxy config manager now because it is a dependency of creating the proxyWatcher - // which will be passed to consul.NewServer so that it is then passed to the - // controller registration for the XDS controller in v2 mode, and the xds server in v1 and v2 mode. - intentionDefaultAllow, err := a.config.ACLResolverSettings.IsDefaultAllow() - if err != nil { - return fmt.Errorf("unexpected ACL default policy value of %q", a.config.ACLResolverSettings.ACLDefaultPolicy) - } - - go a.baseDeps.ViewStore.Run(&lib.StopChannelContext{StopCh: a.shutdownCh}) - - // Start the proxy config manager. - a.proxyConfig, err = proxycfg.NewManager(proxycfg.ManagerConfig{ - DataSources: a.proxyDataSources(), - Logger: a.logger.Named(logging.ProxyConfig), - Source: &structs.QuerySource{ - Datacenter: a.config.Datacenter, - Segment: a.config.SegmentName, - Node: a.config.NodeName, - NodePartition: a.config.PartitionOrEmpty(), - }, - DNSConfig: proxycfg.DNSConfig{ - Domain: a.config.DNSDomain, - AltDomain: a.config.DNSAltDomain, - }, - TLSConfigurator: a.tlsConfigurator, - IntentionDefaultAllow: intentionDefaultAllow, - UpdateRateLimit: a.config.XDSUpdateRateLimit, - }) - if err != nil { - return err - } - - // proxyWatcher will be used in the creation of the XDS server and also - // in the registration of the xds controller. - proxyWatcher := a.getProxyWatcher() + // proxyTracker will be used in the creation of the XDS server and also + // in the registration of the v2 xds controller + var proxyTracker *proxytracker.ProxyTracker // Setup either the client or the server. + var consulServer *consul.Server if c.ServerMode { serverLogger := a.baseDeps.Logger.NamedIntercept(logging.ConsulServer) @@ -722,18 +692,24 @@ func (a *Agent) Start(ctx context.Context) error { metrics.Default(), a.tlsConfigurator, incomingRPCLimiter, + keepalive.ServerParameters{ + Time: a.config.GRPCKeepaliveInterval, + Timeout: a.config.GRPCKeepaliveTimeout, + }, ) - var pt *proxytracker.ProxyTracker if a.baseDeps.UseV2Resources() { - pt = proxyWatcher.(*proxytracker.ProxyTracker) + proxyTracker = proxytracker.NewProxyTracker(proxytracker.ProxyTrackerConfig{ + Logger: a.logger.Named("proxy-tracker"), + SessionLimiter: a.baseDeps.XDSStreamLimiter, + }) } - server, err := consul.NewServer(consulCfg, a.baseDeps.Deps, a.externalGRPCServer, incomingRPCLimiter, serverLogger, pt) + consulServer, err = consul.NewServer(consulCfg, a.baseDeps.Deps, a.externalGRPCServer, incomingRPCLimiter, serverLogger, proxyTracker) if err != nil { return fmt.Errorf("Failed to start Consul server: %v", err) } - incomingRPCLimiter.Register(server) - a.delegate = server + incomingRPCLimiter.Register(consulServer) + a.delegate = consulServer if a.config.PeeringEnabled && a.config.ConnectEnabled { d := servercert.Deps{ @@ -743,7 +719,7 @@ func (a *Agent) Start(ctx context.Context) error { ACLsEnabled: a.config.ACLsEnabled, }, LeafCertManager: a.leafCertManager, - GetStore: func() servercert.Store { return server.FSM().State() }, + GetStore: func() servercert.Store { return consulServer.FSM().State() }, TLSConfigurator: a.tlsConfigurator, } a.certManager = servercert.NewCertManager(d) @@ -757,6 +733,10 @@ func (a *Agent) Start(ctx context.Context) error { metrics.Default(), a.tlsConfigurator, rpcRate.NullRequestLimitsHandler(), + keepalive.ServerParameters{ + Time: a.config.GRPCKeepaliveInterval, + Timeout: a.config.GRPCKeepaliveTimeout, + }, ) client, err := consul.NewClient(consulCfg, a.baseDeps.Deps) @@ -795,6 +775,35 @@ func (a *Agent) Start(ctx context.Context) error { return err } + intentionDefaultAllow, err := a.config.ACLResolverSettings.IsDefaultAllow() + if err != nil { + return fmt.Errorf("unexpected ACL default policy value of %q", a.config.ACLResolverSettings.ACLDefaultPolicy) + } + + go a.baseDeps.ViewStore.Run(&lib.StopChannelContext{StopCh: a.shutdownCh}) + + // Start the proxy config manager. + a.proxyConfig, err = proxycfg.NewManager(proxycfg.ManagerConfig{ + DataSources: a.proxyDataSources(consulServer), + Logger: a.logger.Named(logging.ProxyConfig), + Source: &structs.QuerySource{ + Datacenter: a.config.Datacenter, + Segment: a.config.SegmentName, + Node: a.config.NodeName, + NodePartition: a.config.PartitionOrEmpty(), + }, + DNSConfig: proxycfg.DNSConfig{ + Domain: a.config.DNSDomain, + AltDomain: a.config.DNSAltDomain, + }, + TLSConfigurator: a.tlsConfigurator, + IntentionDefaultAllow: intentionDefaultAllow, + UpdateRateLimit: a.config.XDSUpdateRateLimit, + }) + if err != nil { + return err + } + go localproxycfg.Sync( &lib.StopChannelContext{StopCh: a.shutdownCh}, localproxycfg.SyncConfig{ @@ -803,6 +812,7 @@ func (a *Agent) Start(ctx context.Context) error { Logger: a.proxyConfig.Logger.Named("agent-state"), Tokens: a.baseDeps.Tokens, NodeName: a.config.NodeName, + NodeLocality: a.config.StructLocality(), ResyncFrequency: a.config.LocalProxyConfigResyncInterval, }, ) @@ -847,7 +857,7 @@ func (a *Agent) Start(ctx context.Context) error { } // Start grpc and grpc_tls servers. - if err := a.listenAndServeGRPC(proxyWatcher); err != nil { + if err := a.listenAndServeGRPC(proxyTracker, consulServer); err != nil { return err } @@ -912,29 +922,13 @@ func (a *Agent) Failed() <-chan struct{} { return a.apiServers.failed } -// getProxyWatcher returns the proper implementation of the ProxyWatcher interface. -// It will return a ProxyTracker if "resource-apis" experiment is active. Otherwise, -// it will return a ConfigSource. -func (a *Agent) getProxyWatcher() xds.ProxyWatcher { - if a.baseDeps.UseV2Resources() { - a.logger.Trace("returning proxyTracker for getProxyWatcher") - return proxytracker.NewProxyTracker(proxytracker.ProxyTrackerConfig{ - Logger: a.logger.Named("proxy-tracker"), - SessionLimiter: a.baseDeps.XDSStreamLimiter, - }) - } else { - a.logger.Trace("returning configSource for getProxyWatcher") - return localproxycfg.NewConfigSource(a.proxyConfig) - } -} - // configureXDSServer configures an XDS server with the proper implementation of // the PRoxyWatcher interface and registers the XDS server with Consul's // external facing GRPC server. -func (a *Agent) configureXDSServer(proxyWatcher xds.ProxyWatcher) { +func (a *Agent) configureXDSServer(proxyWatcher xds.ProxyWatcher, server *consul.Server) { // TODO(agentless): rather than asserting the concrete type of delegate, we // should add a method to the Delegate interface to build a ConfigSource. - if server, ok := a.delegate.(*consul.Server); ok { + if server != nil { switch proxyWatcher.(type) { case *proxytracker.ProxyTracker: go func() { @@ -970,12 +964,18 @@ func (a *Agent) configureXDSServer(proxyWatcher xds.ProxyWatcher) { a.xdsServer.Register(a.externalGRPCServer) } -func (a *Agent) listenAndServeGRPC(proxyWatcher xds.ProxyWatcher) error { +func (a *Agent) listenAndServeGRPC(proxyTracker *proxytracker.ProxyTracker, server *consul.Server) error { if len(a.config.GRPCAddrs) < 1 && len(a.config.GRPCTLSAddrs) < 1 { return nil } + var proxyWatcher xds.ProxyWatcher + if a.baseDeps.UseV2Resources() { + proxyWatcher = proxyTracker + } else { + proxyWatcher = localproxycfg.NewConfigSource(a.proxyConfig) + } - a.configureXDSServer(proxyWatcher) + a.configureXDSServer(proxyWatcher, server) // Attempt to spawn listeners var listeners []net.Listener @@ -3687,6 +3687,13 @@ func (a *Agent) loadServices(conf *config.RuntimeConfig, snap map[structs.CheckI } ns := service.NodeService() + + // We currently do not persist locality inherited from the node service + // (it is inherited at runtime). See agent/proxycfg-sources/local/sync.go. + // To support locality-aware service discovery in the future, persisting + // this data may be necessary. This does not impact agent-less deployments + // because locality is explicitly set on service registration there. + chkTypes, err := service.CheckTypes() if err != nil { return fmt.Errorf("Failed to validate checks for service %q: %v", service.Name, err) @@ -4570,7 +4577,7 @@ func (a *Agent) listenerPortLocked(svcID structs.ServiceID, checkID structs.Chec return port, nil } -func (a *Agent) proxyDataSources() proxycfg.DataSources { +func (a *Agent) proxyDataSources(server *consul.Server) proxycfg.DataSources { sources := proxycfg.DataSources{ CARoots: proxycfgglue.CacheCARoots(a.cache), CompiledDiscoveryChain: proxycfgglue.CacheCompiledDiscoveryChain(a.cache), @@ -4597,7 +4604,7 @@ func (a *Agent) proxyDataSources() proxycfg.DataSources { ExportedPeeredServices: proxycfgglue.CacheExportedPeeredServices(a.cache), } - if server, ok := a.delegate.(*consul.Server); ok { + if server != nil { deps := proxycfgglue.ServerDataSourceDeps{ Datacenter: a.config.Datacenter, EventPublisher: a.baseDeps.EventPublisher, diff --git a/agent/agent_endpoint.go b/agent/agent_endpoint.go index dd32bc684350..1048a2e65623 100644 --- a/agent/agent_endpoint.go +++ b/agent/agent_endpoint.go @@ -1166,6 +1166,13 @@ func (s *HTTPHandlers) AgentRegisterService(resp http.ResponseWriter, req *http. // Get the node service. ns := args.NodeService() + + // We currently do not persist locality inherited from the node service + // (it is inherited at runtime). See agent/proxycfg-sources/local/sync.go. + // To support locality-aware service discovery in the future, persisting + // this data may be necessary. This does not impact agent-less deployments + // because locality is explicitly set on service registration there. + if ns.Weights != nil { if err := structs.ValidateWeights(ns.Weights); err != nil { return nil, HTTPError{StatusCode: http.StatusBadRequest, Reason: fmt.Sprintf("Invalid Weights: %v", err)} diff --git a/agent/agent_endpoint_test.go b/agent/agent_endpoint_test.go index 1a021d7b8e4c..ab9a44ff9877 100644 --- a/agent/agent_endpoint_test.go +++ b/agent/agent_endpoint_test.go @@ -90,6 +90,18 @@ func TestAgentEndpointsFailInV2(t *testing.T) { }) } + t.Run("agent-self-with-params", func(t *testing.T) { + req, err := http.NewRequest("GET", "/v1/agent/self?dc=dc1", nil) + require.NoError(t, err) + + resp := httptest.NewRecorder() + a.srv.h.ServeHTTP(resp, req) + require.Equal(t, http.StatusOK, resp.Code) + + _, err = io.ReadAll(resp.Body) + require.NoError(t, err) + }) + checkRequest("PUT", "/v1/agent/maintenance") checkRequest("GET", "/v1/agent/services") checkRequest("GET", "/v1/agent/service/web") diff --git a/agent/agent_test.go b/agent/agent_test.go index 455a8bbb3e66..0b17190dd611 100644 --- a/agent/agent_test.go +++ b/agent/agent_test.go @@ -23,19 +23,12 @@ import ( "os" "path" "path/filepath" - "reflect" "strconv" "strings" "sync" "testing" "time" - "github.com/hashicorp/consul/agent/grpc-external/limiter" - "github.com/hashicorp/consul/agent/proxycfg" - "github.com/hashicorp/consul/agent/proxycfg-sources/local" - "github.com/hashicorp/consul/agent/xds" - proxytracker "github.com/hashicorp/consul/internal/mesh/proxy-tracker" - "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/tcpproxy" @@ -6442,73 +6435,6 @@ func TestAgent_checkServerLastSeen(t *testing.T) { }) } -func TestAgent_getProxyWatcher(t *testing.T) { - type testcase struct { - description string - getExperiments func() []string - expectedType xds.ProxyWatcher - } - testscases := []testcase{ - { - description: "config source is returned when api-resources experiment is not configured", - expectedType: &local.ConfigSource{}, - getExperiments: func() []string { - return []string{} - }, - }, - { - description: "proxy tracker is returned when api-resources experiment is configured", - expectedType: &proxytracker.ProxyTracker{}, - getExperiments: func() []string { - return []string{consul.CatalogResourceExperimentName} - }, - }, - } - for _, tc := range testscases { - caConfig := tlsutil.Config{} - tlsConf, err := tlsutil.NewConfigurator(caConfig, hclog.New(nil)) - require.NoError(t, err) - - bd := BaseDeps{ - Deps: consul.Deps{ - Logger: hclog.NewInterceptLogger(nil), - Tokens: new(token.Store), - TLSConfigurator: tlsConf, - GRPCConnPool: &fakeGRPCConnPool{}, - Registry: resource.NewRegistry(), - }, - RuntimeConfig: &config.RuntimeConfig{ - HTTPAddrs: []net.Addr{ - &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: freeport.GetOne(t)}, - }, - }, - Cache: cache.New(cache.Options{}), - NetRPC: &LazyNetRPC{}, - } - - bd.XDSStreamLimiter = limiter.NewSessionLimiter() - bd.LeafCertManager = leafcert.NewManager(leafcert.Deps{ - CertSigner: leafcert.NewNetRPCCertSigner(bd.NetRPC), - RootsReader: leafcert.NewCachedRootsReader(bd.Cache, "dc1"), - Config: leafcert.Config{}, - }) - - cfg := config.RuntimeConfig{ - BuildDate: time.Date(2000, 1, 1, 0, 0, 1, 0, time.UTC), - } - bd, err = initEnterpriseBaseDeps(bd, &cfg) - require.NoError(t, err) - - bd.Experiments = tc.getExperiments() - - agent, err := New(bd) - require.NoError(t, err) - agent.proxyConfig, err = proxycfg.NewManager(proxycfg.ManagerConfig{Logger: bd.Logger, Source: &structs.QuerySource{}}) - require.NoError(t, err) - require.IsTypef(t, tc.expectedType, agent.getProxyWatcher(), fmt.Sprintf("Expected proxyWatcher to be of type %s", reflect.TypeOf(tc.expectedType))) - } - -} func getExpectedCaPoolByFile(t *testing.T) *x509.CertPool { pool := x509.NewCertPool() data, err := os.ReadFile("../test/ca/root.cer") diff --git a/agent/config/builder.go b/agent/config/builder.go index c7fdcb7dd7c9..852337d08cfb 100644 --- a/agent/config/builder.go +++ b/agent/config/builder.go @@ -1019,6 +1019,8 @@ func (b *builder) build() (rt RuntimeConfig, err error) { GRPCPort: grpcPort, GRPCTLSAddrs: grpcTlsAddrs, GRPCTLSPort: grpcTlsPort, + GRPCKeepaliveInterval: b.durationValWithDefaultMin("performance.grpc_keepalive_interval", c.Performance.GRPCKeepaliveInterval, 30*time.Second, time.Second), + GRPCKeepaliveTimeout: b.durationValWithDefaultMin("performance.grpc_keepalive_timeout", c.Performance.GRPCKeepaliveTimeout, 20*time.Second, time.Second), HTTPMaxConnsPerClient: intVal(c.Limits.HTTPMaxConnsPerClient), HTTPSHandshakeTimeout: b.durationVal("limits.https_handshake_timeout", c.Limits.HTTPSHandshakeTimeout), KVMaxValueSize: uint64Val(c.Limits.KVMaxValueSize), @@ -1730,10 +1732,21 @@ func (b *builder) serviceVal(v *ServiceDefinition) *structs.ServiceDefinition { Checks: checks, Proxy: b.serviceProxyVal(v.Proxy), Connect: b.serviceConnectVal(v.Connect), + Locality: b.serviceLocalityVal(v.Locality), EnterpriseMeta: v.EnterpriseMeta.ToStructs(), } } +func (b *builder) serviceLocalityVal(l *Locality) *structs.Locality { + if l == nil { + return nil + } + return &structs.Locality{ + Region: stringVal(l.Region), + Zone: stringVal(l.Zone), + } +} + func (b *builder) serviceKindVal(v *string) structs.ServiceKind { if v == nil { return structs.ServiceKindTypical diff --git a/agent/config/config.go b/agent/config/config.go index 816f7ae85f17..d620b8c2f4e4 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -404,6 +404,7 @@ type ServiceDefinition struct { EnableTagOverride *bool `mapstructure:"enable_tag_override"` Proxy *ServiceProxy `mapstructure:"proxy"` Connect *ServiceConnect `mapstructure:"connect"` + Locality *Locality `mapstructure:"locality"` EnterpriseMeta `mapstructure:",squash"` } @@ -673,9 +674,11 @@ type HTTPConfig struct { } type Performance struct { - LeaveDrainTime *string `mapstructure:"leave_drain_time"` - RaftMultiplier *int `mapstructure:"raft_multiplier"` // todo(fs): validate as uint - RPCHoldTimeout *string `mapstructure:"rpc_hold_timeout"` + LeaveDrainTime *string `mapstructure:"leave_drain_time"` + RaftMultiplier *int `mapstructure:"raft_multiplier"` // todo(fs): validate as uint + RPCHoldTimeout *string `mapstructure:"rpc_hold_timeout"` + GRPCKeepaliveInterval *string `mapstructure:"grpc_keepalive_interval"` + GRPCKeepaliveTimeout *string `mapstructure:"grpc_keepalive_timeout"` } type Telemetry struct { diff --git a/agent/config/default.go b/agent/config/default.go index cb71d4eedefd..f07a8bdf46dc 100644 --- a/agent/config/default.go +++ b/agent/config/default.go @@ -118,6 +118,8 @@ func DefaultSource() Source { leave_drain_time = "5s" raft_multiplier = ` + strconv.Itoa(int(consul.DefaultRaftMultiplier)) + ` rpc_hold_timeout = "7s" + grpc_keepalive_interval = "30s" + grpc_keepalive_timeout = "20s" } ports = { dns = 8600 diff --git a/agent/config/runtime.go b/agent/config/runtime.go index 18278b08b1ac..954aa7198e25 100644 --- a/agent/config/runtime.go +++ b/agent/config/runtime.go @@ -717,6 +717,19 @@ type RuntimeConfig struct { // hcl: client_addr = string addresses { grpc_tls = string } ports { grpc_tls = int } GRPCTLSAddrs []net.Addr + // GRPCKeepaliveInterval determines how frequently an HTTP2 keepalive will be broadcast + // whenever a GRPC connection is idle. This helps detect xds connections that have died. + // + // Since the xds load balancing between servers relies on knowing how many connections + // are active, this configuration ensures that they are routinely detected / cleaned up + // on an interval. + GRPCKeepaliveInterval time.Duration + + // GRPCKeepaliveTimeout specifies how long a GRPC client has to reply to the keepalive + // messages spawned from GRPCKeepaliveInterval. If a client does not reply in this amount of + // time, the connection will be closed by the server. + GRPCKeepaliveTimeout time.Duration + // HTTPAddrs contains the list of TCP addresses and UNIX sockets the HTTP // server will bind to. If the HTTP endpoint is disabled (ports.http <= 0) // the list is empty. diff --git a/agent/config/runtime_test.go b/agent/config/runtime_test.go index e7772c94a955..7158b014d15d 100644 --- a/agent/config/runtime_test.go +++ b/agent/config/runtime_test.go @@ -6560,6 +6560,8 @@ func TestLoad_FullConfig(t *testing.T) { GRPCAddrs: []net.Addr{tcpAddr("32.31.61.91:4881")}, GRPCTLSPort: 5201, GRPCTLSAddrs: []net.Addr{tcpAddr("23.14.88.19:5201")}, + GRPCKeepaliveInterval: 33 * time.Second, + GRPCKeepaliveTimeout: 22 * time.Second, HTTPAddrs: []net.Addr{tcpAddr("83.39.91.39:7999")}, HTTPBlockEndpoints: []string{"RBvAFcGD", "fWOWFznh"}, AllowWriteHTTPFrom: []*net.IPNet{cidr("127.0.0.0/8"), cidr("22.33.44.55/32"), cidr("0.0.0.0/0")}, @@ -6574,6 +6576,10 @@ func TestLoad_FullConfig(t *testing.T) { KVMaxValueSize: 1234567800, LeaveDrainTime: 8265 * time.Second, LeaveOnTerm: true, + Locality: &Locality{ + Region: strPtr("us-east-2"), + Zone: strPtr("us-east-2b"), + }, Logging: logging.Config{ LogLevel: "k1zo9Spt", LogJSON: true, @@ -6676,6 +6682,10 @@ func TestLoad_FullConfig(t *testing.T) { }, }, }, + Locality: &structs.Locality{ + Region: "us-east-1", + Zone: "us-east-1a", + }, }, { ID: "MRHVMZuD", @@ -6834,6 +6844,10 @@ func TestLoad_FullConfig(t *testing.T) { Connect: &structs.ServiceConnect{ Native: true, }, + Locality: &structs.Locality{ + Region: "us-west-1", + Zone: "us-west-1a", + }, Checks: structs.CheckTypes{ &structs.CheckType{ CheckID: "Zv99e9Ka", diff --git a/agent/config/testdata/TestRuntimeConfig_Sanitize.golden b/agent/config/testdata/TestRuntimeConfig_Sanitize.golden index b82baea53514..56397ad94d0f 100644 --- a/agent/config/testdata/TestRuntimeConfig_Sanitize.golden +++ b/agent/config/testdata/TestRuntimeConfig_Sanitize.golden @@ -210,6 +210,8 @@ "GRPCPort": 0, "GRPCTLSAddrs": [], "GRPCTLSPort": 0, + "GRPCKeepaliveInterval": "0s", + "GRPCKeepaliveTimeout": "0s", "GossipLANGossipInterval": "0s", "GossipLANGossipNodes": 0, "GossipLANProbeInterval": "0s", diff --git a/agent/config/testdata/full-config.hcl b/agent/config/testdata/full-config.hcl index 1c1fb0158aa5..4c734265fd41 100644 --- a/agent/config/testdata/full-config.hcl +++ b/agent/config/testdata/full-config.hcl @@ -317,6 +317,10 @@ limits { write_rate = 101.0 } } +locality = { + region = "us-east-2" + zone = "us-east-2b" +} log_level = "k1zo9Spt" log_json = true max_query_time = "18237s" @@ -335,6 +339,8 @@ performance { leave_drain_time = "8265s" raft_multiplier = 5 rpc_hold_timeout = "15707s" + grpc_keepalive_interval = "33s" + grpc_keepalive_timeout = "22s" } pid_file = "43xN80Km" ports { @@ -508,6 +514,10 @@ service = { connect { native = true } + locality = { + region = "us-west-1" + zone = "us-west-1a" + } } services = [ { @@ -548,6 +558,10 @@ services = [ connect { sidecar_service {} } + locality = { + region = "us-east-1" + zone = "us-east-1a" + } }, { id = "MRHVMZuD" diff --git a/agent/config/testdata/full-config.json b/agent/config/testdata/full-config.json index cd407d3e5dae..30ede7dd18f1 100644 --- a/agent/config/testdata/full-config.json +++ b/agent/config/testdata/full-config.json @@ -366,6 +366,10 @@ "write_rate": 101.0 } }, + "locality": { + "region": "us-east-2", + "zone": "us-east-2b" + }, "log_level": "k1zo9Spt", "log_json": true, "max_query_time": "18237s", @@ -383,7 +387,9 @@ "performance": { "leave_drain_time": "8265s", "raft_multiplier": 5, - "rpc_hold_timeout": "15707s" + "rpc_hold_timeout": "15707s", + "grpc_keepalive_interval": "33s", + "grpc_keepalive_timeout": "22s" }, "pid_file": "43xN80Km", "ports": { @@ -596,6 +602,10 @@ ], "connect": { "native": true + }, + "locality": { + "region": "us-west-1", + "zone": "us-west-1a" } }, "services": [ @@ -647,6 +657,10 @@ }, "connect": { "sidecar_service": {} + }, + "locality": { + "region": "us-east-1", + "zone": "us-east-1a" } }, { diff --git a/agent/connect/ca/provider_vault.go b/agent/connect/ca/provider_vault.go index 60627b5314a2..692b9a568c23 100644 --- a/agent/connect/ca/provider_vault.go +++ b/agent/connect/ca/provider_vault.go @@ -22,6 +22,7 @@ import ( "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/lib/decode" + "github.com/hashicorp/consul/lib/retry" ) const ( @@ -177,11 +178,17 @@ func (v *VaultProvider) Configure(cfg ProviderConfig) error { v.stopWatcher() } v.stopWatcher = cancel + // NOTE: Any codepaths after v.renewToken(...) which return an error + // _must_ call v.stopWatcher() to prevent the renewal goroutine from + // leaking when the CA initialization fails and gets retried later. go v.renewToken(ctx, lifetimeWatcher) } // Update the intermediate (managed) PKI mount and role if err := v.setupIntermediatePKIPath(); err != nil { + if v.stopWatcher != nil { + v.stopWatcher() + } return err } @@ -223,6 +230,16 @@ func (v *VaultProvider) renewToken(ctx context.Context, watcher *vaultapi.Lifeti go watcher.Start() defer watcher.Stop() + // These values are chosen to start the exponential backoff + // immediately. Since the Vault client implements its own + // retries, this retry is mostly to avoid resource contention + // and log spam. + retrier := retry.Waiter{ + MinFailures: 1, + MinWait: 1 * time.Second, + Jitter: retry.NewJitter(20), + } + for { select { case <-ctx.Done(): @@ -231,7 +248,16 @@ func (v *VaultProvider) renewToken(ctx context.Context, watcher *vaultapi.Lifeti case err := <-watcher.DoneCh(): // Watcher has stopped if err != nil { - v.logger.Error("Error renewing token for Vault provider", "error", err) + v.logger.Error("Error renewing token for Vault provider", "error", err, "retries", retrier.Failures()) + } + + // Although the vault watcher has its own retry logic, we have encountered + // issues when passing an invalid Vault token which would send an error to + // watcher.DoneCh() immediately, causing us to start the watcher over and + // over again in a very tight loop. + if err := retrier.Wait(ctx); err != nil { + // only possible error is when context is cancelled + return } // If the watcher has exited and auth method is enabled, @@ -265,6 +291,7 @@ func (v *VaultProvider) renewToken(ctx context.Context, watcher *vaultapi.Lifeti go watcher.Start() case <-watcher.RenewCh(): + retrier.Reset() v.logger.Info("Successfully renewed token for Vault provider") } } diff --git a/agent/connect/ca/provider_vault_test.go b/agent/connect/ca/provider_vault_test.go index ece7659d04aa..edd094f5502a 100644 --- a/agent/connect/ca/provider_vault_test.go +++ b/agent/connect/ca/provider_vault_test.go @@ -8,6 +8,7 @@ import ( "encoding/json" "fmt" "io" + "runtime/pprof" "strconv" "strings" "sync/atomic" @@ -237,8 +238,69 @@ func TestVaultCAProvider_Configure(t *testing.T) { testcase.expectedValue(t, provider) }) } +} + +// This test must not run in parallel +func TestVaultCAProvider_ConfigureFailureGoroutineLeakCheck(t *testing.T) { + if testing.Short() { + t.Skip("too slow for testing.Short") + } + SkipIfVaultNotPresent(t) + + testVault := NewTestVaultServer(t) + + attr := &VaultTokenAttributes{ + RootPath: "pki-root", + IntermediatePath: "pki-intermediate", + ConsulManaged: true, + } + token := CreateVaultTokenWithAttrs(t, testVault.client, attr) + + provider := NewVaultProvider(hclog.New(&hclog.LoggerOptions{Name: "ca.vault"})) + + t.Run("error on Configure does not leak renewal routine", func(t *testing.T) { + config := map[string]any{ + "RootPKIPath": "pki-root/", + "IntermediatePKIPath": "badbadbad/", + } + cfg := vaultProviderConfig(t, testVault.Addr, token, config) + + err := provider.Configure(cfg) + require.Error(t, err) + + retry.RunWith(retry.TwoSeconds(), t, func(r *retry.R) { + profile := pprof.Lookup("goroutine") + sb := strings.Builder{} + require.NoError(r, profile.WriteTo(&sb, 2)) + require.NotContains(r, sb.String(), + "created by github.com/hashicorp/consul/agent/connect/ca.(*VaultProvider).Configure", + "found renewal goroutine leak") + // If this test is failing because you added a new goroutine to + // (*VaultProvider).Configure AND that goroutine should persist + // even if Configure errored, then you should change the checked + // string to (*VaultProvider).renewToken. + }) + }) - return + t.Run("successful Configure starts renewal routine", func(t *testing.T) { + config := map[string]any{ + "RootPKIPath": "pki-root/", + "IntermediatePKIPath": "pki-intermediate/", + } + cfg := vaultProviderConfig(t, testVault.Addr, token, config) + + require.NoError(t, provider.Configure(cfg)) + + retry.RunWith(retry.TwoSeconds(), t, func(r *retry.R) { + profile := pprof.Lookup("goroutine") + sb := strings.Builder{} + require.NoError(r, profile.WriteTo(&sb, 2)) + t.Log(sb.String()) + require.Contains(r, sb.String(), + "created by github.com/hashicorp/consul/agent/connect/ca.(*VaultProvider).Configure", + "expected renewal goroutine, got none") + }) + }) } func TestVaultCAProvider_SecondaryActiveIntermediate(t *testing.T) { diff --git a/agent/consul/discoverychain/gateway_httproute.go b/agent/consul/discoverychain/gateway_httproute.go index 3a4acf48e413..c4816e027449 100644 --- a/agent/consul/discoverychain/gateway_httproute.go +++ b/agent/consul/discoverychain/gateway_httproute.go @@ -177,12 +177,9 @@ func httpRouteToDiscoveryChain(route structs.HTTPRouteConfigEntry) (*structs.Ser } if rule.Filters.RetryFilter != nil { - if rule.Filters.RetryFilter.NumRetries != nil { - destination.NumRetries = *rule.Filters.RetryFilter.NumRetries - } - if rule.Filters.RetryFilter.RetryOnConnectFailure != nil { - destination.RetryOnConnectFailure = *rule.Filters.RetryFilter.RetryOnConnectFailure - } + + destination.NumRetries = rule.Filters.RetryFilter.NumRetries + destination.RetryOnConnectFailure = rule.Filters.RetryFilter.RetryOnConnectFailure if len(rule.Filters.RetryFilter.RetryOn) > 0 { destination.RetryOn = rule.Filters.RetryFilter.RetryOn diff --git a/agent/consul/gateways/controller_gateways.go b/agent/consul/gateways/controller_gateways.go index 24e1dd4c275a..ae82bdddc449 100644 --- a/agent/consul/gateways/controller_gateways.go +++ b/agent/consul/gateways/controller_gateways.go @@ -686,14 +686,16 @@ func (g *gatewayMeta) updateRouteBinding(route structs.BoundRoute) (bool, []stru errors[ref] = err } + isValidJWT := true if httpRoute, ok := route.(*structs.HTTPRouteConfigEntry); ok { var jwtErrors map[structs.ResourceReference]error - didBind, jwtErrors = g.validateJWTForRoute(httpRoute) + isValidJWT, jwtErrors = g.validateJWTForRoute(httpRoute) for ref, err := range jwtErrors { errors[ref] = err } } - if didBind { + + if didBind && isValidJWT { refDidBind = true listenerBound[listener.Name] = true } diff --git a/agent/consul/server_test.go b/agent/consul/server_test.go index e8058a468a3f..0ae028cbf2f2 100644 --- a/agent/consul/server_test.go +++ b/agent/consul/server_test.go @@ -26,6 +26,7 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/time/rate" "google.golang.org/grpc" + "google.golang.org/grpc/keepalive" "github.com/hashicorp/consul-net-rpc/net/rpc" @@ -335,7 +336,7 @@ func newServerWithDeps(t *testing.T, c *Config, deps Deps) (*Server, error) { oldNotify() } } - grpcServer := external.NewServer(deps.Logger.Named("grpc.external"), nil, deps.TLSConfigurator, rpcRate.NullRequestLimitsHandler()) + grpcServer := external.NewServer(deps.Logger.Named("grpc.external"), nil, deps.TLSConfigurator, rpcRate.NullRequestLimitsHandler(), keepalive.ServerParameters{}) srv, err := NewServer(c, deps, grpcServer, nil, deps.Logger, nil) if err != nil { return nil, err diff --git a/agent/grpc-external/server.go b/agent/grpc-external/server.go index 6090a8f31a15..30af8f2e6e1a 100644 --- a/agent/grpc-external/server.go +++ b/agent/grpc-external/server.go @@ -27,7 +27,13 @@ var ( // NewServer constructs a gRPC server for the external gRPC port, to which // handlers can be registered. -func NewServer(logger agentmiddleware.Logger, metricsObj *metrics.Metrics, tls *tlsutil.Configurator, limiter rate.RequestLimitsHandler) *grpc.Server { +func NewServer( + logger agentmiddleware.Logger, + metricsObj *metrics.Metrics, + tls *tlsutil.Configurator, + limiter rate.RequestLimitsHandler, + keepaliveParams keepalive.ServerParameters, +) *grpc.Server { if metricsObj == nil { metricsObj = metrics.Default() } @@ -56,6 +62,7 @@ func NewServer(logger agentmiddleware.Logger, metricsObj *metrics.Metrics, tls * grpc.StatsHandler(agentmiddleware.NewStatsHandler(metricsObj, metricsLabels)), middleware.WithUnaryServerChain(unaryInterceptors...), middleware.WithStreamServerChain(streamInterceptors...), + grpc.KeepaliveParams(keepaliveParams), grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{ // This must be less than the keealive.ClientParameters Time setting, otherwise // the server will disconnect the client for sending too many keepalive pings. diff --git a/agent/grpc-external/services/resource/read.go b/agent/grpc-external/services/resource/read.go index 351a50385655..b6cec3725456 100644 --- a/agent/grpc-external/services/resource/read.go +++ b/agent/grpc-external/services/resource/read.go @@ -50,7 +50,7 @@ func (s *Server) Read(ctx context.Context, req *pbresource.ReadRequest) (*pbreso authzNeedsData := false err = reg.ACLs.Read(authz, authzContext, req.Id, nil) switch { - case errors.Is(err, resource.ErrNeedData): + case errors.Is(err, resource.ErrNeedResource): authzNeedsData = true err = nil case acl.IsErrPermissionDenied(err): diff --git a/agent/grpc-external/stats_test.go b/agent/grpc-external/stats_test.go index 798c900148ba..3bd5c777cd16 100644 --- a/agent/grpc-external/stats_test.go +++ b/agent/grpc-external/stats_test.go @@ -14,6 +14,7 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" "google.golang.org/grpc" + "google.golang.org/grpc/keepalive" "github.com/hashicorp/go-hclog" @@ -27,7 +28,7 @@ import ( func TestServer_EmitsStats(t *testing.T) { sink, metricsObj := testutil.NewFakeSink(t) - srv := NewServer(hclog.Default(), metricsObj, nil, rate.NullRequestLimitsHandler()) + srv := NewServer(hclog.Default(), metricsObj, nil, rate.NullRequestLimitsHandler(), keepalive.ServerParameters{}) testservice.RegisterSimpleServer(srv, &testservice.Simple{}) diff --git a/agent/http.go b/agent/http.go index e95d36c914f8..aed7c920cdf9 100644 --- a/agent/http.go +++ b/agent/http.go @@ -396,7 +396,7 @@ func (s *HTTPHandlers) wrap(handler endpoint, methods []string) http.HandlerFunc rejectCatalogV1Endpoint := false if s.agent.baseDeps.UseV2Resources() { - rejectCatalogV1Endpoint = isV1CatalogRequest(logURL) + rejectCatalogV1Endpoint = isV1CatalogRequest(req.URL.Path) } if s.denylist.Block(req.URL.Path) { diff --git a/agent/pool/pool.go b/agent/pool/pool.go index 899cefe2e974..d793dcd4a1de 100644 --- a/agent/pool/pool.go +++ b/agent/pool/pool.go @@ -49,6 +49,7 @@ type Conn struct { refCount int32 shouldClose int32 + dc string nodeName string addr net.Addr session muxSession @@ -234,7 +235,7 @@ func (p *ConnPool) acquire(dc string, nodeName string, addr net.Addr) (*Conn, er addrStr := addr.String() - poolKey := nodeName + ":" + addrStr + poolKey := makePoolKey(dc, nodeName, addrStr) // Check to see if there's a pooled connection available. This is up // here since it should the vastly more common case than the rest @@ -493,6 +494,7 @@ func (p *ConnPool) getNewConn(dc string, nodeName string, addr net.Addr) (*Conn, // Wrap the connection c := &Conn{ refCount: 1, + dc: dc, nodeName: nodeName, addr: addr, session: session, @@ -514,7 +516,7 @@ func (p *ConnPool) clearConn(conn *Conn) { // Clear from the cache addrStr := conn.addr.String() - poolKey := conn.nodeName + ":" + addrStr + poolKey := makePoolKey(conn.dc, conn.nodeName, addrStr) p.Lock() if c, ok := p.pool[poolKey]; ok && c == conn { delete(p.pool, poolKey) @@ -716,3 +718,8 @@ func (p *ConnPool) reap() { p.Unlock() } } + +// makePoolKey generates a unique key for grouping connections together into a pool. +func makePoolKey(dc, nodeName, addrStr string) string { + return dc + ":" + nodeName + ":" + addrStr +} diff --git a/agent/proxycfg-sources/local/sync.go b/agent/proxycfg-sources/local/sync.go index b5583db43a3d..54d95e6594f2 100644 --- a/agent/proxycfg-sources/local/sync.go +++ b/agent/proxycfg-sources/local/sync.go @@ -5,9 +5,10 @@ package local import ( "context" - proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" "time" + proxysnapshot "github.com/hashicorp/consul/internal/mesh/proxy-snapshot" + "github.com/hashicorp/go-hclog" "github.com/hashicorp/consul/agent/local" @@ -35,6 +36,9 @@ type SyncConfig struct { // NodeName is the name of the local agent node. NodeName string + // NodeLocality + NodeLocality *structs.Locality + // Logger will be used to write log messages. Logger hclog.Logger @@ -110,6 +114,14 @@ func sync(cfg SyncConfig) { Token: "", } + // We inherit the node's locality at runtime (not persisted). + // The service locality takes precedence if it was set directly during + // registration. + svc = svc.DeepCopy() + if svc.Locality == nil { + svc.Locality = cfg.NodeLocality + } + // TODO(banks): need to work out when to default some stuff. For example // Proxy.LocalServicePort is practically necessary for any sidecar and can // default to the port of the sidecar service, but only if it's already diff --git a/agent/proxycfg-sources/local/sync_test.go b/agent/proxycfg-sources/local/sync_test.go index 5aa030db4cfc..b20787140df5 100644 --- a/agent/proxycfg-sources/local/sync_test.go +++ b/agent/proxycfg-sources/local/sync_test.go @@ -72,8 +72,12 @@ func TestSync(t *testing.T) { go Sync(ctx, SyncConfig{ Manager: cfgMgr, State: state, - Tokens: tokens, - Logger: hclog.NewNullLogger(), + NodeLocality: &structs.Locality{ + Region: "some-region", + Zone: "some-zone", + }, + Tokens: tokens, + Logger: hclog.NewNullLogger(), }) // Expect the service in the local state to be registered. @@ -107,6 +111,13 @@ func TestSync(t *testing.T) { select { case reg := <-registerCh: require.Equal(t, serviceID, reg.service.ID) + require.Equal(t, + &structs.Locality{ + Region: "some-region", + Zone: "some-zone", + }, + reg.service.Locality, + ) require.Equal(t, userToken, reg.token) case <-time.After(100 * time.Millisecond): t.Fatal("timeout waiting for service to be registered") diff --git a/agent/rpc/peering/service_test.go b/agent/rpc/peering/service_test.go index 8fde278c8b7f..b2b207515720 100644 --- a/agent/rpc/peering/service_test.go +++ b/agent/rpc/peering/service_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/require" gogrpc "google.golang.org/grpc" "google.golang.org/grpc/codes" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" grpcstatus "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" @@ -1818,7 +1819,7 @@ func newTestServer(t *testing.T, cb func(conf *consul.Config)) testingServer { conf.ACLResolverSettings.EnterpriseMeta = *conf.AgentEnterpriseMeta() deps := newDefaultDeps(t, conf) - externalGRPCServer := external.NewServer(deps.Logger, nil, deps.TLSConfigurator, rate.NullRequestLimitsHandler()) + externalGRPCServer := external.NewServer(deps.Logger, nil, deps.TLSConfigurator, rate.NullRequestLimitsHandler(), keepalive.ServerParameters{}) server, err := consul.NewServer(conf, deps, externalGRPCServer, nil, deps.Logger, nil) require.NoError(t, err) diff --git a/agent/structs/config_entry.go b/agent/structs/config_entry.go index a844a9de8545..544820f4d607 100644 --- a/agent/structs/config_entry.go +++ b/agent/structs/config_entry.go @@ -418,6 +418,7 @@ type InstanceLevelRateLimits struct { RequestsMaxBurst int `alias:"requests_max_burst"` // Routes is a list of rate limits applied to specific routes. + // For a given request, the first matching route will be applied, if any. // Overrides any top-level configuration. Routes []InstanceLevelRouteRateLimits } diff --git a/agent/structs/config_entry_routes.go b/agent/structs/config_entry_routes.go index 7f764c93c725..741404769e5d 100644 --- a/agent/structs/config_entry_routes.go +++ b/agent/structs/config_entry_routes.go @@ -475,10 +475,10 @@ type URLRewrite struct { } type RetryFilter struct { - NumRetries *uint32 + NumRetries uint32 RetryOn []string RetryOnStatusCodes []uint32 - RetryOnConnectFailure *bool + RetryOnConnectFailure bool } type TimeoutFilter struct { diff --git a/agent/structs/structs.deepcopy.go b/agent/structs/structs.deepcopy.go index 8a2b95f2964a..017b0c943ca6 100644 --- a/agent/structs/structs.deepcopy.go +++ b/agent/structs/structs.deepcopy.go @@ -400,10 +400,6 @@ func (o *HTTPRouteConfigEntry) DeepCopy() *HTTPRouteConfigEntry { if o.Rules[i2].Filters.RetryFilter != nil { cp.Rules[i2].Filters.RetryFilter = new(RetryFilter) *cp.Rules[i2].Filters.RetryFilter = *o.Rules[i2].Filters.RetryFilter - if o.Rules[i2].Filters.RetryFilter.NumRetries != nil { - cp.Rules[i2].Filters.RetryFilter.NumRetries = new(uint32) - *cp.Rules[i2].Filters.RetryFilter.NumRetries = *o.Rules[i2].Filters.RetryFilter.NumRetries - } if o.Rules[i2].Filters.RetryFilter.RetryOn != nil { cp.Rules[i2].Filters.RetryFilter.RetryOn = make([]string, len(o.Rules[i2].Filters.RetryFilter.RetryOn)) copy(cp.Rules[i2].Filters.RetryFilter.RetryOn, o.Rules[i2].Filters.RetryFilter.RetryOn) @@ -412,10 +408,6 @@ func (o *HTTPRouteConfigEntry) DeepCopy() *HTTPRouteConfigEntry { cp.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes = make([]uint32, len(o.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes)) copy(cp.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes, o.Rules[i2].Filters.RetryFilter.RetryOnStatusCodes) } - if o.Rules[i2].Filters.RetryFilter.RetryOnConnectFailure != nil { - cp.Rules[i2].Filters.RetryFilter.RetryOnConnectFailure = new(bool) - *cp.Rules[i2].Filters.RetryFilter.RetryOnConnectFailure = *o.Rules[i2].Filters.RetryFilter.RetryOnConnectFailure - } } if o.Rules[i2].Filters.TimeoutFilter != nil { cp.Rules[i2].Filters.TimeoutFilter = new(TimeoutFilter) @@ -493,10 +485,6 @@ func (o *HTTPRouteConfigEntry) DeepCopy() *HTTPRouteConfigEntry { if o.Rules[i2].Services[i4].Filters.RetryFilter != nil { cp.Rules[i2].Services[i4].Filters.RetryFilter = new(RetryFilter) *cp.Rules[i2].Services[i4].Filters.RetryFilter = *o.Rules[i2].Services[i4].Filters.RetryFilter - if o.Rules[i2].Services[i4].Filters.RetryFilter.NumRetries != nil { - cp.Rules[i2].Services[i4].Filters.RetryFilter.NumRetries = new(uint32) - *cp.Rules[i2].Services[i4].Filters.RetryFilter.NumRetries = *o.Rules[i2].Services[i4].Filters.RetryFilter.NumRetries - } if o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn != nil { cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn = make([]string, len(o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn)) copy(cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn, o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOn) @@ -505,10 +493,6 @@ func (o *HTTPRouteConfigEntry) DeepCopy() *HTTPRouteConfigEntry { cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes = make([]uint32, len(o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes)) copy(cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes, o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnStatusCodes) } - if o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnConnectFailure != nil { - cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnConnectFailure = new(bool) - *cp.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnConnectFailure = *o.Rules[i2].Services[i4].Filters.RetryFilter.RetryOnConnectFailure - } } if o.Rules[i2].Services[i4].Filters.TimeoutFilter != nil { cp.Rules[i2].Services[i4].Filters.TimeoutFilter = new(TimeoutFilter) diff --git a/agent/xds/clusters.go b/agent/xds/clusters.go index 3f0ba0d7f31b..b74fe371b28d 100644 --- a/agent/xds/clusters.go +++ b/agent/xds/clusters.go @@ -641,10 +641,13 @@ func (s *ResourceGenerator) makePeerServerClusters(cfgSnap *proxycfg.ConfigSnaps var cluster *envoy_cluster_v3.Cluster if servers.UseCDS { + // we use strict DNS here since multiple gateways with hostnames + // would result in an invalid cluster due to logical DNS requiring + // only a single host cluster = s.makeExternalHostnameCluster(cfgSnap, clusterOpts{ name: name, addresses: servers.Addresses, - }) + }, envoy_cluster_v3.Cluster_STRICT_DNS) } else { cluster = s.makeGatewayCluster(cfgSnap, clusterOpts{ name: name, @@ -842,7 +845,7 @@ func (s *ResourceGenerator) makeDestinationClusters(cfgSnap *proxycfg.ConfigSnap if structs.IsIP(address) { cluster = s.makeExternalIPCluster(cfgSnap, opts) } else { - cluster = s.makeExternalHostnameCluster(cfgSnap, opts) + cluster = s.makeExternalHostnameCluster(cfgSnap, opts, envoy_cluster_v3.Cluster_LOGICAL_DNS) } if err := s.injectGatewayDestinationAddons(cfgSnap, cluster, svcName); err != nil { return nil, err @@ -1865,8 +1868,8 @@ func (s *ResourceGenerator) makeExternalIPCluster(snap *proxycfg.ConfigSnapshot, } // makeExternalHostnameCluster creates an Envoy cluster for hostname endpoints that will be resolved with DNS -// This is used by both terminating gateways for Destinations, and Mesh Gateways for peering control plane traffice -func (s *ResourceGenerator) makeExternalHostnameCluster(snap *proxycfg.ConfigSnapshot, opts clusterOpts) *envoy_cluster_v3.Cluster { +// This is used by both terminating gateways for Destinations, and Mesh Gateways for peering control plane traffic +func (s *ResourceGenerator) makeExternalHostnameCluster(snap *proxycfg.ConfigSnapshot, opts clusterOpts, discoveryType envoy_cluster_v3.Cluster_DiscoveryType) *envoy_cluster_v3.Cluster { cfg, err := config.ParseGatewayConfig(snap.Proxy.Config) if err != nil { // Don't hard fail on a config typo, just warn. The parse func returns @@ -1881,7 +1884,7 @@ func (s *ResourceGenerator) makeExternalHostnameCluster(snap *proxycfg.ConfigSna // Having an empty config enables outlier detection with default config. OutlierDetection: &envoy_cluster_v3.OutlierDetection{}, - ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_LOGICAL_DNS}, + ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{Type: discoveryType}, DnsLookupFamily: envoy_cluster_v3.Cluster_V4_ONLY, } diff --git a/agent/xds/endpoints.go b/agent/xds/endpoints.go index ff486f3228a8..2fb0a4a1df59 100644 --- a/agent/xds/endpoints.go +++ b/agent/xds/endpoints.go @@ -880,13 +880,7 @@ func makeLoadAssignment(logger hclog.Logger, cfgSnap *proxycfg.ConfigSnapshot, c Endpoints: make([]*envoy_endpoint_v3.LocalityLbEndpoints, 0, len(endpointGroups)), } - if len(endpointGroups) > 1 { - cla.Policy = &envoy_endpoint_v3.ClusterLoadAssignment_Policy{ - // We choose such a large value here that the failover math should - // in effect not happen until zero instances are healthy. - OverprovisioningFactor: response.MakeUint32Value(100000), - } - } + setFullFailoverProvisioningFactor := len(endpointGroups) > 1 var priority uint32 @@ -897,6 +891,10 @@ func makeLoadAssignment(logger hclog.Logger, cfgSnap *proxycfg.ConfigSnapshot, c continue } + if len(endpointsByLocality) > 1 { + setFullFailoverProvisioningFactor = true + } + for _, endpoints := range endpointsByLocality { es := make([]*envoy_endpoint_v3.LbEndpoint, 0, len(endpointGroup.Endpoints)) @@ -930,6 +928,14 @@ func makeLoadAssignment(logger hclog.Logger, cfgSnap *proxycfg.ConfigSnapshot, c } } + if setFullFailoverProvisioningFactor { + cla.Policy = &envoy_endpoint_v3.ClusterLoadAssignment_Policy{ + // We choose such a large value here that the failover math should + // in effect not happen until zero instances are healthy. + OverprovisioningFactor: response.MakeUint32Value(100000), + } + } + return cla } diff --git a/agent/xds/listeners_apigateway.go b/agent/xds/listeners_apigateway.go index a4611895e290..771a48297203 100644 --- a/agent/xds/listeners_apigateway.go +++ b/agent/xds/listeners_apigateway.go @@ -152,7 +152,11 @@ func (s *ResourceGenerator) makeAPIGatewayListeners(address string, cfgSnap *pro routes := make([]*structs.HTTPRouteConfigEntry, 0, len(readyListener.routeReferences)) for _, routeRef := range maps.Keys(readyListener.routeReferences) { - route, _ := cfgSnap.APIGateway.HTTPRoutes.Get(routeRef) + route, ok := cfgSnap.APIGateway.HTTPRoutes.Get(routeRef) + if !ok { + return nil, fmt.Errorf("missing route for routeRef %s:%s", routeRef.Kind, routeRef.Name) + } + routes = append(routes, route) } consolidatedRoutes := discoverychain.ConsolidateHTTPRoutes(cfgSnap.APIGateway.GatewayConfig, &readyListener.listenerCfg, routes...) @@ -297,11 +301,9 @@ func getReadyListeners(cfgSnap *proxycfg.ConfigSnapshot) map[string]readyListene continue } - routeKey := l.Name + routeRef.String() - for _, upstream := range routeUpstreamsForListener { // Insert or update readyListener for the listener to include this upstream - r, ok := ready[routeKey] + r, ok := ready[l.Name] if !ok { r = readyListener{ listenerKey: listenerKey, @@ -312,7 +314,7 @@ func getReadyListeners(cfgSnap *proxycfg.ConfigSnapshot) map[string]readyListene } r.routeReferences[routeRef] = struct{}{} r.upstreams = append(r.upstreams, upstream) - ready[routeKey] = r + ready[l.Name] = r } } } diff --git a/agent/xds/proxystateconverter/clusters.go b/agent/xds/proxystateconverter/clusters.go index cb084a4283ca..b8857bee29c5 100644 --- a/agent/xds/proxystateconverter/clusters.go +++ b/agent/xds/proxystateconverter/clusters.go @@ -462,7 +462,7 @@ func (s *Converter) makeAppCluster(cfgSnap *proxycfg.ConfigSnapshot, name, pathP if protocol == "" { protocol = cfg.Protocol } - namedCluster.cluster.Protocol = protocol + namedCluster.cluster.Protocol = protocolMap[protocol] if cfg.MaxInboundConnections > 0 { namedCluster.cluster.GetEndpointGroup().GetStatic().GetConfig(). CircuitBreakers = &pbproxystate.CircuitBreakers{ @@ -646,7 +646,7 @@ func (s *Converter) makeUpstreamClusterForPreparedQuery(upstream structs.Upstrea if c == nil { c = &pbproxystate.Cluster{ - Protocol: cfg.Protocol, + Protocol: protocolMap[cfg.Protocol], Group: &pbproxystate.Cluster_EndpointGroup{ EndpointGroup: &pbproxystate.EndpointGroup{ Group: &pbproxystate.EndpointGroup_Dynamic{ @@ -932,7 +932,7 @@ func (s *Converter) makeUpstreamClustersForDiscoveryChain( } else { cluster := &pbproxystate.Cluster{ AltStatName: mappedTargets.baseClusterName, - Protocol: upstreamConfig.Protocol, + Protocol: protocolMap[upstreamConfig.Protocol], Group: &pbproxystate.Cluster_EndpointGroup{ EndpointGroup: &pbproxystate.EndpointGroup{ Group: &pbproxystate.EndpointGroup_Dynamic{ @@ -952,7 +952,7 @@ func (s *Converter) makeUpstreamClustersForDiscoveryChain( failoverGroup.EndpointGroups = endpointGroups cluster := &pbproxystate.Cluster{ AltStatName: mappedTargets.baseClusterName, - Protocol: upstreamConfig.Protocol, + Protocol: protocolMap[upstreamConfig.Protocol], Group: &pbproxystate.Cluster_FailoverGroup{ FailoverGroup: failoverGroup, }, @@ -1251,3 +1251,13 @@ func makeOutlierDetection(p *structs.PassiveHealthCheck, override *structs.Passi return od } + +// protocolMap converts config entry protocols to proxystate protocol values. +// As documented on config entry protos, the valid values are "tcp", "http", +// "http2" and "grpc". Anything else is treated as tcp. +var protocolMap = map[string]pbproxystate.Protocol{ + "http": pbproxystate.Protocol_PROTOCOL_HTTP, + "http2": pbproxystate.Protocol_PROTOCOL_HTTP2, + "grpc": pbproxystate.Protocol_PROTOCOL_GRPC, + "tcp": pbproxystate.Protocol_PROTOCOL_TCP, +} diff --git a/agent/xds/resources_test.go b/agent/xds/resources_test.go index 69a704386b5d..b47edcbac368 100644 --- a/agent/xds/resources_test.go +++ b/agent/xds/resources_test.go @@ -14,8 +14,6 @@ import ( envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" - "k8s.io/utils/pointer" - "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/agent/consul/discoverychain" "github.com/hashicorp/consul/agent/xds/testcommon" @@ -571,10 +569,10 @@ func getAPIGatewayGoldenTestCases(t *testing.T) []goldenTestCase { }, }, RetryFilter: &structs.RetryFilter{ - NumRetries: pointer.Uint32(3), + NumRetries: 3, RetryOn: []string{"cancelled"}, RetryOnStatusCodes: []uint32{500}, - RetryOnConnectFailure: pointer.Bool(true), + RetryOnConnectFailure: true, }, TimeoutFilter: &structs.TimeoutFilter{ IdleTimeout: time.Second * 30, diff --git a/agent/xds/testdata/clusters/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden b/agent/xds/testdata/clusters/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden index 462e9f406b62..2d1ec4439e70 100644 --- a/agent/xds/testdata/clusters/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden +++ b/agent/xds/testdata/clusters/mesh-gateway-with-peer-through-mesh-gateway-enabled.latest.golden @@ -53,7 +53,7 @@ }, "name": "server.dc3.peering.f622dc37-7238-4485-ab58-0f53864a9ae5", "outlierDetection": {}, - "type": "LOGICAL_DNS" + "type": "STRICT_DNS" } ], "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", diff --git a/agent/xds/testdata/routes/api-gateway-with-multiple-hostnames.latest.golden b/agent/xds/testdata/routes/api-gateway-with-multiple-hostnames.latest.golden index 9e96457f3c3b..b268a5e5ac5e 100644 --- a/agent/xds/testdata/routes/api-gateway-with-multiple-hostnames.latest.golden +++ b/agent/xds/testdata/routes/api-gateway-with-multiple-hostnames.latest.golden @@ -8,52 +8,38 @@ "virtualHosts": [ { "domains": [ - "backend.example.com", - "backend.example.com:8080" + "frontend.example.com", + "frontend.example.com:8080" ], - "name": "api-gateway-http-5a84e719", + "name": "api-gateway-http-54620b06", "routes": [ { "match": { "prefix": "/" }, "route": { - "cluster": "backend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "frontend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "8080", - "validateClusters": true, - "virtualHosts": [ + }, { "domains": [ - "frontend.example.com", - "frontend.example.com:8080" + "backend.example.com", + "backend.example.com:8080" ], - "name": "api-gateway-http-54620b06", + "name": "api-gateway-http-5a84e719", "routes": [ { "match": { "prefix": "/" }, "route": { - "cluster": "frontend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" + "cluster": "backend.default.dc1.internal.11111111-2222-3333-4444-555555555555.consul" } } ] - } - ] - }, - { - "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", - "name": "8080", - "validateClusters": true, - "virtualHosts": [ + }, { "domains": [ "*.example.com", diff --git a/agent/xdsv2/cluster_resources.go b/agent/xdsv2/cluster_resources.go index 06ff21f51908..d32eeed2ec62 100644 --- a/agent/xdsv2/cluster_resources.go +++ b/agent/xdsv2/cluster_resources.go @@ -81,7 +81,7 @@ func (pr *ProxyResources) makeClusters(name string) ([]proto.Message, error) { return clusters, nil } -func (pr *ProxyResources) makeEnvoyCluster(name string, protocol string, eg *pbproxystate.EndpointGroup) (*envoy_cluster_v3.Cluster, error) { +func (pr *ProxyResources) makeEnvoyCluster(name string, protocol pbproxystate.Protocol, eg *pbproxystate.EndpointGroup) (*envoy_cluster_v3.Cluster, error) { if eg != nil { switch t := eg.Group.(type) { case *pbproxystate.EndpointGroup_Dynamic: @@ -103,7 +103,7 @@ func (pr *ProxyResources) makeEnvoyCluster(name string, protocol string, eg *pbp return nil, fmt.Errorf("no endpoint group") } -func (pr *ProxyResources) makeEnvoyDynamicCluster(name string, protocol string, dynamic *pbproxystate.DynamicEndpointGroup) (*envoy_cluster_v3.Cluster, error) { +func (pr *ProxyResources) makeEnvoyDynamicCluster(name string, protocol pbproxystate.Protocol, dynamic *pbproxystate.DynamicEndpointGroup) (*envoy_cluster_v3.Cluster, error) { cluster := &envoy_cluster_v3.Cluster{ Name: name, ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_EDS}, @@ -153,7 +153,7 @@ func (pr *ProxyResources) makeEnvoyDynamicCluster(name string, protocol string, } -func (pr *ProxyResources) makeEnvoyStaticCluster(name string, protocol string, static *pbproxystate.StaticEndpointGroup) (*envoy_cluster_v3.Cluster, error) { +func (pr *ProxyResources) makeEnvoyStaticCluster(name string, protocol pbproxystate.Protocol, static *pbproxystate.StaticEndpointGroup) (*envoy_cluster_v3.Cluster, error) { cluster := &envoy_cluster_v3.Cluster{ Name: name, ClusterDiscoveryType: &envoy_cluster_v3.Cluster_Type{Type: envoy_cluster_v3.Cluster_STATIC}, @@ -182,11 +182,11 @@ func (pr *ProxyResources) makeEnvoyStaticCluster(name string, protocol string, s return cluster, nil } -func (pr *ProxyResources) makeEnvoyDnsCluster(name string, protocol string, dns *pbproxystate.DNSEndpointGroup) (*envoy_cluster_v3.Cluster, error) { +func (pr *ProxyResources) makeEnvoyDnsCluster(name string, protocol pbproxystate.Protocol, dns *pbproxystate.DNSEndpointGroup) (*envoy_cluster_v3.Cluster, error) { return nil, nil } -func (pr *ProxyResources) makeEnvoyPassthroughCluster(name string, protocol string, passthrough *pbproxystate.PassthroughEndpointGroup) (*envoy_cluster_v3.Cluster, error) { +func (pr *ProxyResources) makeEnvoyPassthroughCluster(name string, protocol pbproxystate.Protocol, passthrough *pbproxystate.PassthroughEndpointGroup) (*envoy_cluster_v3.Cluster, error) { cluster := &envoy_cluster_v3.Cluster{ Name: name, ConnectTimeout: passthrough.Config.ConnectTimeout, @@ -207,7 +207,7 @@ func (pr *ProxyResources) makeEnvoyPassthroughCluster(name string, protocol stri return cluster, nil } -func (pr *ProxyResources) makeEnvoyAggregateCluster(name string, protocol string, fg *pbproxystate.FailoverGroup) ([]*envoy_cluster_v3.Cluster, error) { +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 @@ -250,8 +250,8 @@ func (pr *ProxyResources) makeEnvoyAggregateCluster(name string, protocol string return clusters, nil } -func addLocalAppHttpProtocolOptions(protocol string, c *envoy_cluster_v3.Cluster) error { - if !(protocol == "http2" || protocol == "grpc") { +func addLocalAppHttpProtocolOptions(protocol pbproxystate.Protocol, c *envoy_cluster_v3.Cluster) error { + if !(protocol == pbproxystate.Protocol_PROTOCOL_HTTP2 || protocol == pbproxystate.Protocol_PROTOCOL_GRPC) { // do not error. returning nil means it won't get set. return nil } @@ -274,8 +274,8 @@ func addLocalAppHttpProtocolOptions(protocol string, c *envoy_cluster_v3.Cluster return nil } -func addHttpProtocolOptions(protocol string, c *envoy_cluster_v3.Cluster) error { - if !(protocol == "http2" || protocol == "grpc") { +func addHttpProtocolOptions(protocol pbproxystate.Protocol, c *envoy_cluster_v3.Cluster) error { + if !(protocol == pbproxystate.Protocol_PROTOCOL_HTTP2 || protocol == pbproxystate.Protocol_PROTOCOL_GRPC) { // do not error. returning nil means it won't get set. return nil } diff --git a/agent/xdsv2/resources_test.go b/agent/xdsv2/resources_test.go index e84e9bdb513c..c1afbda705be 100644 --- a/agent/xdsv2/resources_test.go +++ b/agent/xdsv2/resources_test.go @@ -4,8 +4,11 @@ package xdsv2 import ( - "os" - "path/filepath" + "fmt" + envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" + envoy_route_v3 "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" + envoy_tls_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/transport_sockets/tls/v3" + "github.com/hashicorp/consul/internal/testing/golden" "sort" "testing" @@ -23,62 +26,111 @@ import ( "google.golang.org/protobuf/proto" ) -func TestResources_ImplicitDestinations(t *testing.T) { +var testTypeUrlToPrettyName = map[string]string{ + xdscommon.ListenerType: "listeners", + xdscommon.RouteType: "routes", + xdscommon.ClusterType: "clusters", + xdscommon.EndpointType: "endpoints", + xdscommon.SecretType: "secrets", +} - cases := map[string]struct { - }{ - "l4-single-implicit-destination-tproxy": {}, +// TestAllResourcesFromIR_XDSGoldenFileInputs tests the AllResourcesFromIR() by +// using the golden test output/expected files from the XDS controller tests as +// inputs to the XDSV2 resources generation. +func TestAllResourcesFromIR_XDSGoldenFileInputs(t *testing.T) { + inputPath := "../../internal/mesh/internal/controllers/xds" + + cases := []string{ + // destinations - please add in alphabetical order + "destination/l4-single-destination-ip-port-bind-address", + "destination/l4-single-destination-unix-socket-bind-address", + "destination/l4-single-implicit-destination-tproxy", + "destination/l4-multi-destination", + "destination/l4-multiple-implicit-destinations-tproxy", + "destination/l4-implicit-and-explicit-destinations-tproxy", + "destination/mixed-multi-destination", + "destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy", + "destination/multiport-l4-and-l7-single-implicit-destination-tproxy", + "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/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 { - goldenValueInput := goldenValueJSON(t, name, "input") - - proxyTemplate := jsonToProxyTemplate(t, goldenValueInput) - generator := NewResourceGenerator(testutil.Logger(t)) - - resources, err := generator.AllResourcesFromIR(&proxytracker.ProxyState{ProxyState: proxyTemplate.ProxyState}) - require.NoError(t, err) - - verifyClusterResourcesToGolden(t, resources, name) - verifyListenerResourcesToGolden(t, resources, name) - + for _, name := range cases { + t.Run(name, func(t *testing.T) { + // Arrange - paths to input and output golden files. + testFile := fmt.Sprintf("%s.golden", name) + inputFilePath := fmt.Sprintf("%s/testdata/%s", inputPath, testFile) + inputValueInput := golden.GetBytesAtFilePath(t, inputFilePath) + + // Act. + ps := jsonToProxyState(t, inputValueInput) + generator := NewResourceGenerator(testutil.Logger(t)) + resources, err := generator.AllResourcesFromIR(&proxytracker.ProxyState{ProxyState: ps}) + require.NoError(t, err) + + // Assert. + // Assert all resources were generated. + typeUrls := []string{ + xdscommon.ListenerType, + xdscommon.RouteType, + xdscommon.ClusterType, + xdscommon.EndpointType, + // TODO(proxystate): add in future + //xdscommon.SecretType, + } + require.Len(t, resources, len(typeUrls)) + + // Assert each resource type has actual XDS matching expected XDS. + for _, typeUrl := range typeUrls { + prettyName := testTypeUrlToPrettyName[typeUrl] + t.Run(prettyName, func(t *testing.T) { + items, ok := resources[typeUrl] + require.True(t, ok) + + // sort resources so they don't show up as flakey tests as + // ordering in JSON is not guaranteed. + 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") + } + }) + + // Compare actual to expected. + resp, err := response.CreateResponse(typeUrl, "00000001", "00000001", items) + require.NoError(t, err) + gotJSON := protoToJSON(t, resp) + + expectedJSON := golden.Get(t, gotJSON, fmt.Sprintf("%s/%s", prettyName, testFile)) + require.JSONEq(t, expectedJSON, gotJSON) + }) + } + }) } } -func verifyClusterResourcesToGolden(t *testing.T, resources map[string][]proto.Message, testName string) { - clusters := resources[xdscommon.ClusterType] - - // The order of clusters returned via CDS isn't relevant, so it's safe - // to sort these for the purposes of test comparisons. - sort.Slice(clusters, func(i, j int) bool { - return clusters[i].(*envoy_cluster_v3.Cluster).Name < clusters[j].(*envoy_cluster_v3.Cluster).Name - }) - - resp, err := response.CreateResponse(xdscommon.ClusterType, "00000001", "00000001", clusters) - require.NoError(t, err) - gotJSON := protoToJSON(t, resp) - - expectedJSON := goldenValue(t, filepath.Join("clusters", testName), "output") - require.JSONEq(t, expectedJSON, gotJSON) -} - -func verifyListenerResourcesToGolden(t *testing.T, resources map[string][]proto.Message, testName string) { - listeners := resources[xdscommon.ListenerType] - - // The order of clusters returned via CDS isn't relevant, so it's safe - // to sort these for the purposes of test comparisons. - sort.Slice(listeners, func(i, j int) bool { - return listeners[i].(*envoy_listener_v3.Listener).Name < listeners[j].(*envoy_listener_v3.Listener).Name - }) - - resp, err := response.CreateResponse(xdscommon.ListenerType, "00000001", "00000001", listeners) - require.NoError(t, err) - gotJSON := protoToJSON(t, resp) - - expectedJSON := goldenValue(t, filepath.Join("listeners", testName), "output") - require.JSONEq(t, expectedJSON, gotJSON) -} - func protoToJSON(t *testing.T, pb proto.Message) string { t.Helper() m := protojson.MarshalOptions{ @@ -89,25 +141,11 @@ func protoToJSON(t *testing.T, pb proto.Message) string { return string(gotJSON) } -func jsonToProxyTemplate(t *testing.T, json []byte) *meshv2beta1.ProxyStateTemplate { +func jsonToProxyState(t *testing.T, json []byte) *meshv2beta1.ProxyState { t.Helper() um := protojson.UnmarshalOptions{} - proxyTemplate := &meshv2beta1.ProxyStateTemplate{} - err := um.Unmarshal(json, proxyTemplate) - require.NoError(t, err) - return proxyTemplate -} - -func goldenValueJSON(t *testing.T, goldenFile, inputOutput string) []byte { - t.Helper() - goldenPath := filepath.Join("testdata", inputOutput, goldenFile) + ".golden" - - content, err := os.ReadFile(goldenPath) + ps := &meshv2beta1.ProxyState{} + err := um.Unmarshal(json, ps) require.NoError(t, err) - return content -} - -func goldenValue(t *testing.T, goldenFile, inputOutput string) string { - t.Helper() - return string(goldenValueJSON(t, goldenFile, inputOutput)) + return ps } diff --git a/agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy.golden new file mode 100644 index 000000000000..089bfb7c2003 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/l4-implicit-and-explicit-destinations-tproxy.golden @@ -0,0 +1,110 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "original-destination", + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" + }, + { + "@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": {} + }, + "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/api1-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "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" + } + }, + "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~tcp" + ] + }, + "sni": "api-2.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-multi-destination.golden b/agent/xdsv2/testdata/clusters/destination/l4-multi-destination.golden new file mode 100644 index 000000000000..c88d7770d85f --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/l4-multi-destination.golden @@ -0,0 +1,205 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@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" + } + }, + "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/api1-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "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" + } + }, + "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~tcp" + ] + }, + "sni": "api-2.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp2.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/api1-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp2" + ] + }, + "sni": "api-1.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp2.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~tcp2" + ] + }, + "sni": "api-2.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy.golden new file mode 100644 index 000000000000..089bfb7c2003 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/l4-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,110 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "original-destination", + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" + }, + { + "@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": {} + }, + "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/api1-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "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" + } + }, + "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~tcp" + ] + }, + "sni": "api-2.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address.golden b/agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address.golden new file mode 100644 index 000000000000..293416e3737f --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/l4-single-destination-ip-port-bind-address.golden @@ -0,0 +1,109 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@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" + } + }, + "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/api1-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "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" + } + }, + "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~tcp" + ] + }, + "sni": "api-2.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address.golden b/agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address.golden new file mode 100644 index 000000000000..742dbd0ea838 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/l4-single-destination-unix-socket-bind-address.golden @@ -0,0 +1,55 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@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": {} + }, + "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~tcp" + ] + }, + "sni": "api-2.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy.golden new file mode 100644 index 000000000000..0c86051ad7df --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/l4-single-implicit-destination-tproxy.golden @@ -0,0 +1,62 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "original-destination", + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" + }, + { + "@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": {} + }, + "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/api1-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "sni": "api-1.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden new file mode 100644 index 000000000000..280f42b8581f --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/mixed-multi-destination.golden @@ -0,0 +1,157 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@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": "tcp.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/api1-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "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" + } + }, + "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~tcp" + ] + }, + "sni": "api-2.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden new file mode 100644 index 000000000000..ec39ef35787f --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,302 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "http.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~http" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "http.api-app2.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/api-app2-identity" + } + ] + }, + "alpnProtocols": [ + "consul~http" + ] + }, + "sni": "api-app2.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "original-destination", + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp.api-app2.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/api-app2-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "sni": "api-app2.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp2.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp2" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp2.api-app2.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/api-app2-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp2" + ] + }, + "sni": "api-app2.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden new file mode 100644 index 000000000000..d8cad46e7904 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden @@ -0,0 +1,158 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "http.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~http" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "original-destination", + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp2.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp2" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden new file mode 100644 index 000000000000..d8cad46e7904 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -0,0 +1,158 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "http.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~http" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "original-destination", + "type": "ORIGINAL_DST", + "connectTimeout": "5s", + "lbPolicy": "CLUSTER_PROVIDED" + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "tcp2.api-app.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/api-app-identity" + } + ] + }, + "alpnProtocols": [ + "consul~tcp2" + ] + }, + "sni": "api-app.default.dc1.internal.foo.consul" + } + } + } + ], + "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 000000000000..ce9870c06cd9 --- /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 000000000000..ce9870c06cd9 --- /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 000000000000..ce9870c06cd9 --- /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/l7-expose-paths.golden b/agent/xdsv2/testdata/clusters/source/l7-expose-paths.golden new file mode 100644 index 000000000000..a83751b4b502 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/l7-expose-paths.golden @@ -0,0 +1,87 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exposed_cluster_9090", + "type": "STATIC", + "loadAssignment": { + "clusterName": "exposed_cluster_9090", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exposed_cluster_9091", + "type": "STATIC", + "loadAssignment": { + "clusterName": "exposed_cluster_9091", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9091 + } + } + } + } + ] + } + ] + }, + "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: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/local-and-inbound-connections.golden b/agent/xdsv2/testdata/clusters/source/local-and-inbound-connections.golden new file mode 100644 index 000000000000..d4e6fd1d64ce --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/local-and-inbound-connections.golden @@ -0,0 +1,127 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exposed_cluster_9090", + "type": "STATIC", + "loadAssignment": { + "clusterName": "exposed_cluster_9090", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "exposed_cluster_9091", + "type": "STATIC", + "loadAssignment": { + "clusterName": "exposed_cluster_9091", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9091 + } + } + } + } + ] + } + ] + }, + "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:port1", + "type": "STATIC", + "connectTimeout": "6s", + "loadAssignment": { + "clusterName": "local_app:port1", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + }, + "circuitBreakers": { + "thresholds": [ + { + "maxConnections": 123 + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:port3", + "type": "STATIC", + "connectTimeout": "8s", + "loadAssignment": { + "clusterName": "local_app:port3", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8081 + } + } + } + } + ] + } + ] + }, + "circuitBreakers": { + "thresholds": [ + { + "maxConnections": 123 + } + ] + } + } + ], + "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/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..045470a3e572 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,55 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:admin-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:admin-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:api-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:api-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + } + } + ], + "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/multiport-l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..045470a3e572 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/multiport-l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,55 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:admin-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:admin-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:api-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:api-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + } + } + ], + "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/multiport-l4-workload-with-only-mesh-port.golden b/agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port.golden new file mode 100644 index 000000000000..460d515fe589 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/multiport-l4-workload-with-only-mesh-port.golden @@ -0,0 +1,12 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "black-hole-cluster", + "type": "STATIC" + } + ], + "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/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..339faaae6b0d --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,63 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:admin-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:admin-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:api-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:api-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + }, + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + } + ], + "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/multiport-l7-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..6246f19733b8 --- /dev/null +++ b/agent/xdsv2/testdata/clusters/source/multiport-l7-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,95 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:admin-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:admin-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + } + }, + { + "@type": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "name": "local_app:api-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:api-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + }, + "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:grpc-port", + "type": "STATIC", + "loadAssignment": { + "clusterName": "local_app:grpc-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9091 + } + } + } + } + ] + } + ] + }, + "typedExtensionProtocolOptions": { + "envoy.extensions.upstreams.http.v3.HttpProtocolOptions": { + "@type": "type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions", + "explicitHttpConfig": { + "http2ProtocolOptions": {} + } + } + } + } + ], + "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy.golden new file mode 100644 index 000000000000..f7d569dc2266 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/l4-implicit-and-explicit-destinations-tproxy.golden @@ -0,0 +1,49 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-multi-destination.golden b/agent/xdsv2/testdata/endpoints/destination/l4-multi-destination.golden new file mode 100644 index 000000000000..f8bca7ea3212 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/l4-multi-destination.golden @@ -0,0 +1,91 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp2.api-1.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp2.api-2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy.golden new file mode 100644 index 000000000000..f7d569dc2266 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/l4-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,49 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address.golden b/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address.golden new file mode 100644 index 000000000000..f7d569dc2266 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-ip-port-bind-address.golden @@ -0,0 +1,49 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address.golden b/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address.golden new file mode 100644 index 000000000000..8075b842d96c --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/l4-single-destination-unix-socket-bind-address.golden @@ -0,0 +1,28 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy.golden new file mode 100644 index 000000000000..333765ea0cb2 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/l4-single-implicit-destination-tproxy.golden @@ -0,0 +1,28 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination.golden new file mode 100644 index 000000000000..e22812cafe4b --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/mixed-multi-destination.golden @@ -0,0 +1,91 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "http.api-1.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "http.api-2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden new file mode 100644 index 000000000000..56ff9fb5884b --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,133 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "http.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "http.api-app2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-app2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp2.api-app2.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden new file mode 100644 index 000000000000..52f227f9d4b8 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden @@ -0,0 +1,70 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "http.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden new file mode 100644 index 000000000000..52f227f9d4b8 --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -0,0 +1,70 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "http.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "10.1.1.1", + "portValue": 20000 + } + } + }, + "healthStatus": "HEALTHY" + } + ] + } + ] + } + ], + "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-with-specific-ports.golden b/agent/xdsv2/testdata/endpoints/source/l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..b0c31e6e79c7 --- /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 000000000000..b0c31e6e79c7 --- /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 000000000000..b0c31e6e79c7 --- /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/l7-expose-paths.golden b/agent/xdsv2/testdata/endpoints/source/l7-expose-paths.golden new file mode 100644 index 000000000000..1ccb234c89db --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/l7-expose-paths.golden @@ -0,0 +1,67 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "exposed_cluster_9090", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "exposed_cluster_9091", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9091 + } + } + } + } + ] + } + ] + }, + { + "@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/local-and-inbound-connections.golden b/agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections.golden new file mode 100644 index 000000000000..c9e8727f031d --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/local-and-inbound-connections.golden @@ -0,0 +1,87 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "exposed_cluster_9090", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "exposed_cluster_9091", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9091 + } + } + } + } + ] + } + ] + }, + { + "@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 + } + } + } + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:port3", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8081 + } + } + } + } + ] + } + ] + } + ], + "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/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..916fbc26ceab --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,47 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:admin-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:api-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + } + ], + "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/multiport-l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..916fbc26ceab --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/multiport-l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,47 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:admin-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:api-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + } + ], + "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/multiport-l4-workload-with-only-mesh-port.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port.golden new file mode 100644 index 000000000000..47b46bca225b --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/multiport-l4-workload-with-only-mesh-port.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "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/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..916fbc26ceab --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,47 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:admin-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:api-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + } + ], + "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/multiport-l7-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..e3c67d2c90ae --- /dev/null +++ b/agent/xdsv2/testdata/endpoints/source/multiport-l7-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,67 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:admin-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 8080 + } + } + } + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:api-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9090 + } + } + } + } + ] + } + ] + }, + { + "@type": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "clusterName": "local_app:grpc-port", + "endpoints": [ + { + "lbEndpoints": [ + { + "endpoint": { + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 9091 + } + } + } + } + ] + } + ] + } + ], + "typeUrl": "type.googleapis.com/envoy.config.endpoint.v3.ClusterLoadAssignment", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/input/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/input/l4-single-implicit-destination-tproxy.golden deleted file mode 100644 index feaa68bd3c23..000000000000 --- a/agent/xdsv2/testdata/input/l4-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,110 +0,0 @@ -{ - "proxyState": { - "identity": { - "tenancy": { - "partition": "default", - "namespace": "default", - "peerName": "local" - }, - "name": "test-identity" - }, - "listeners": [ - { - "name": "outbound_listener", - "direction": "DIRECTION_OUTBOUND", - "hostPort": { - "host": "127.0.0.1", - "port": 15001 - }, - "routers": [ - { - "match": { - "prefixRanges": [ - { - "addressPrefix": "1.1.1.1", - "prefixLen": 32 - } - ], - "destinationPort": 8080 - }, - "l4": { - "cluster": { - "name": "tcp.api-1.default.dc1.internal.foo.consul" - }, - "statPrefix": "upstream.tcp.api-1.default.default.dc1" - } - } - ], - "capabilities": [ - "CAPABILITY_TRANSPARENT" - ], - "defaultRouter": { - "l4": { - "cluster": { - "name": "original-destination" - }, - "statPrefix": "upstream.original-destination" - } - } - } - ], - "clusters": { - "tcp.api-1.default.dc1.internal.foo.consul": { - "endpointGroup": { - "dynamic": { - "config": { - "disablePanicThreshold": true - }, - "outboundTls": { - "outboundMesh": { - "identityKey": "test-identity", - "validationContext": { - "spiffeIds": [ - "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - ], - "trustBundlePeerNameKey": "local" - }, - "sni": "api-1.default.dc1.internal.foo.consul" - }, - "alpnProtocols": [ - "consul~tcp" - ] - } - } - } - } - }, - "leafCertificates": { - "test-identity": { - "cert": "cert1", - "key": "key1" - } - }, - "trustBundles": { - "local": { - "trustDomain": "foo.consul", - "roots": [ - "root1" - ] - } - } - }, - "requiredEndpoints": { - "api-1.default.dc1.internal.foo.consul": { - "id": { - "name": "api-1", - "type": { - "group": "catalog", - "groupVersion": "v1alpha1", - "kind": "ServiceEndpoints" - }, - "tenancy": { - "partition": "default", - "namespace": "default", - "peerName": "local" - } - }, - "port": "mesh" - } - } -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy.golden new file mode 100644 index 000000000000..35304ea0d7f5 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/l4-implicit-and-explicit-destinations-tproxy.golden @@ -0,0 +1,90 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "address": { + "socketAddress": { + "address": "1.1.1.1", + "portValue": 1234 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "cluster": "tcp.api-1.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-2.default.default.dc1", + "cluster": "tcp.api-2.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, + "listenerFilters": [ + { + "name": "envoy.filters.listener.original_dst", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" + } + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-multi-destination.golden b/agent/xdsv2/testdata/listeners/destination/l4-multi-destination.golden new file mode 100644 index 000000000000..105b508ef52c --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/l4-multi-destination.golden @@ -0,0 +1,137 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-1:tcp2:1.1.1.1:2345", + "address": { + "socketAddress": { + "address": "1.1.1.1", + "portValue": 2345 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp2.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp2.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp2.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "address": { + "socketAddress": { + "address": "1.1.1.1", + "portValue": 1234 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-2:tcp2:/path/to/socket", + "address": { + "pipe": { + "path": "/path/to/socket", + "mode": 438 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp2.api-2.default.default.dc1", + "cluster": "tcp2.api-2.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-2:tcp:/path/to/socket", + "address": { + "pipe": { + "path": "/path/to/socket", + "mode": 438 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-2.default.default.dc1", + "cluster": "tcp.api-2.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy.golden new file mode 100644 index 000000000000..7901233ae959 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/l4-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,86 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "cluster": "tcp.api-1.default.dc1.internal.foo.consul" + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-2.default.default.dc1", + "cluster": "tcp.api-2.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, + "listenerFilters": [ + { + "name": "envoy.filters.listener.original_dst", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" + } + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address.golden b/agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address.golden new file mode 100644 index 000000000000..5f78003e3fd8 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/l4-single-destination-ip-port-bind-address.golden @@ -0,0 +1,47 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "address": { + "socketAddress": { + "address": "1.1.1.1", + "portValue": 1234 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address.golden b/agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address.golden new file mode 100644 index 000000000000..cf468d7fbbcf --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/l4-single-destination-unix-socket-bind-address.golden @@ -0,0 +1,32 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-2:tcp:/path/to/socket", + "address": { + "pipe": { + "path": "/path/to/socket", + "mode": 438 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-2.default.default.dc1", + "cluster": "tcp.api-2.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/output/listeners/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy.golden similarity index 78% rename from agent/xdsv2/testdata/output/listeners/l4-single-implicit-destination-tproxy.golden rename to agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy.golden index d34b4e610793..ce759b6b0211 100644 --- a/agent/xdsv2/testdata/output/listeners/l4-single-implicit-destination-tproxy.golden +++ b/agent/xdsv2/testdata/listeners/destination/l4-single-implicit-destination-tproxy.golden @@ -10,22 +10,10 @@ "portValue": 15001 } }, - "defaultFilterChain": { - "filters": [ - { - "name": "envoy.filters.network.tcp_proxy", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", - "cluster": "original-destination", - "statPrefix": "upstream.original-destination" - } - } - ] - }, "filterChains": [ { "filterChainMatch": { - "destinationPort": 8080, + "destinationPort": 7070, "prefixRanges": [ { "addressPrefix": "1.1.1.1", @@ -45,6 +33,18 @@ ] } ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, "listenerFilters": [ { "name": "envoy.filters.listener.original_dst", diff --git a/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden new file mode 100644 index 000000000000..23dd5e4c6475 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/mixed-multi-destination.golden @@ -0,0 +1,119 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-1:http:1.1.1.1:1234", + "address": { + "socketAddress": { + "address": "1.1.1.1", + "portValue": 1234 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "default/local/default/api-1:http:1.1.1.1:1234" + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "address": { + "socketAddress": { + "address": "1.1.1.1", + "portValue": 1234 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "default/local/default/api-2:tcp:/path/to/socket", + "address": { + "pipe": { + "path": "/path/to/socket", + "mode": 438 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-2.default.default.dc1", + "cluster": "tcp.api-2.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file 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 new file mode 100644 index 000000000000..9cd146e6ef0d --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,222 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-app.default.default.dc1", + "cluster": "tcp.api-app.default.dc1.internal.foo.consul" + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 8080, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "default/local/default/api-app:http" + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp2.api-app.default.default.dc1", + "cluster": "tcp2.api-app.default.dc1.internal.foo.consul" + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-app2.default.default.dc1", + "cluster": "tcp.api-app2.default.dc1.internal.foo.consul" + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 8080, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "default/local/default/api-app2:http" + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp2.api-app2.default.default.dc1", + "cluster": "tcp2.api-app2.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, + "listenerFilters": [ + { + "name": "envoy.filters.listener.original_dst", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" + } + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file 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 new file mode 100644 index 000000000000..71dec1b4db46 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden @@ -0,0 +1,125 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-app.default.default.dc1", + "cluster": "tcp.api-app.default.dc1.internal.foo.consul" + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 8080, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "default/local/default/api-app:http" + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp2.api-app.default.default.dc1", + "cluster": "tcp2.api-app.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, + "listenerFilters": [ + { + "name": "envoy.filters.listener.original_dst", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" + } + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "typeUrl": "type.googleapis.com/envoy.config.listener.v3.Listener", + "nonce": "00000001" +} \ No newline at end of file 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 new file mode 100644 index 000000000000..71dec1b4db46 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -0,0 +1,125 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "outbound_listener", + "address": { + "socketAddress": { + "address": "127.0.0.1", + "portValue": 15001 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp.api-app.default.default.dc1", + "cluster": "tcp.api-app.default.dc1.internal.foo.consul" + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 8080, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "upstream.", + "rds": { + "configSource": { + "ads": {}, + "resourceApiVersion": "V3" + }, + "routeConfigName": "default/local/default/api-app:http" + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + }, + { + "filterChainMatch": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + }, + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.tcp2.api-app.default.default.dc1", + "cluster": "tcp2.api-app.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "defaultFilterChain": { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "upstream.original-destination", + "cluster": "original-destination" + } + } + ] + }, + "listenerFilters": [ + { + "name": "envoy.filters.listener.original_dst", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.original_dst.v3.OriginalDst" + } + } + ], + "trafficDirection": "OUTBOUND" + } + ], + "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-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..644769d8423f --- /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 000000000000..82581d576248 --- /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 000000000000..82581d576248 --- /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/l7-expose-paths.golden b/agent/xdsv2/testdata/listeners/source/l7-expose-paths.golden new file mode 100644 index 000000000000..973c825a6c63 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/l7-expose-paths.golden @@ -0,0 +1,201 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_GetHealth1235", + "address": { + "socketAddress": { + "address": "10.0.0.1", + "portValue": 1235 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "exposed_path_route_GetHealth1235", + "routeConfig": { + "name": "exposed_path_route_GetHealth1235", + "virtualHosts": [ + { + "name": "exposed_path_route_GetHealth1235", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "path": "GetHealth" + }, + "route": { + "cluster": "exposed_cluster_9091" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "http2ProtocolOptions": {}, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + } + ], + "trafficDirection": "INBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_health1234", + "address": { + "socketAddress": { + "address": "10.0.0.1", + "portValue": 1234 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "exposed_path_route_health1234", + "routeConfig": { + "name": "exposed_path_route_health1234", + "virtualHosts": [ + { + "name": "exposed_path_route_health1234", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "path": "/health" + }, + "route": { + "cluster": "exposed_cluster_9090" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + } + ], + "trafficDirection": "INBOUND" + }, + { + "@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/local-and-inbound-connections.golden b/agent/xdsv2/testdata/listeners/source/local-and-inbound-connections.golden new file mode 100644 index 000000000000..916961daaf9f --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/local-and-inbound-connections.golden @@ -0,0 +1,309 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_GetHealth1235", + "address": { + "socketAddress": { + "address": "10.0.0.1", + "portValue": 1235 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "exposed_path_route_GetHealth1235", + "routeConfig": { + "name": "exposed_path_route_GetHealth1235", + "virtualHosts": [ + { + "name": "exposed_path_route_GetHealth1235", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "path": "GetHealth" + }, + "route": { + "cluster": "exposed_cluster_9091" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "http2ProtocolOptions": {}, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + } + ], + "trafficDirection": "INBOUND" + }, + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "exposed_path_health1234", + "address": { + "socketAddress": { + "address": "10.0.0.1", + "portValue": 1234 + } + }, + "filterChains": [ + { + "filters": [ + { + "name": "envoy.filters.network.http_connection_manager", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager", + "statPrefix": "exposed_path_route_health1234", + "routeConfig": { + "name": "exposed_path_route_health1234", + "virtualHosts": [ + { + "name": "exposed_path_route_health1234", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "path": "/health" + }, + "route": { + "cluster": "exposed_cluster_9090" + } + } + ] + } + ] + }, + "httpFilters": [ + { + "name": "envoy.filters.http.router", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router" + } + } + ], + "tracing": { + "randomSampling": {} + }, + "upgradeConfigs": [ + { + "upgradeType": "websocket" + } + ] + } + } + ] + } + ], + "trafficDirection": "INBOUND" + }, + { + "@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.connection_limit", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit", + "statPrefix": "inbound_connection_limit", + "maxConnections": "123" + } + }, + { + "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 + } + } + }, + { + "filterChainMatch": { + "applicationProtocols": [ + "consul~port3" + ] + }, + "filters": [ + { + "name": "envoy.filters.network.connection_limit", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.connection_limit.v3.ConnectionLimit", + "statPrefix": "inbound_connection_limit", + "maxConnections": "123" + } + }, + { + "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:port3", + "virtualHosts": [ + { + "name": "public_listener:port3", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:port3", + "timeout": "9s" + } + } + ] + } + ] + }, + "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 + } + } + } + ], + "listenerFilters": [ + { + "name": "envoy.filters.listener.tls_inspector", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector" + } + } + ], + "trafficDirection": "INBOUND", + "connectionBalanceConfig": { + "exactBalance": {} + } + } + ], + "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/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..10fcbb9c9b6c --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,128 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener", + "address": { + "socketAddress": { + "address": "10.0.0.3", + "portValue": 20000 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "applicationProtocols": [ + "consul~admin-port" + ] + }, + "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:admin-port" + } + } + ], + "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 + } + } + }, + { + "filterChainMatch": { + "applicationProtocols": [ + "consul~api-port" + ] + }, + "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:api-port" + } + } + ], + "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/multiport-l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..ba8670185485 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/multiport-l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,128 @@ +{ + "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~admin-port" + ] + }, + "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:admin-port" + } + } + ], + "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 + } + } + }, + { + "filterChainMatch": { + "applicationProtocols": [ + "consul~api-port" + ] + }, + "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:api-port" + } + } + ], + "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/multiport-l4-workload-with-only-mesh-port.golden b/agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port.golden new file mode 100644 index 000000000000..15d019e69ca5 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/multiport-l4-workload-with-only-mesh-port.golden @@ -0,0 +1,40 @@ +{ + "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": [ + { + "filters": [ + { + "name": "envoy.filters.network.tcp_proxy", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy", + "statPrefix": "public_listener", + "cluster": "black-hole-cluster" + } + } + ] + } + ], + "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/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..1f0d971a9905 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,206 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.listener.v3.Listener", + "name": "public_listener", + "address": { + "socketAddress": { + "address": "10.0.0.3", + "portValue": 20000 + } + }, + "filterChains": [ + { + "filterChainMatch": { + "applicationProtocols": [ + "consul~admin-port" + ] + }, + "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:admin-port", + "virtualHosts": [ + { + "name": "public_listener:admin-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:admin-port" + } + } + ] + } + ] + }, + "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~api-port" + ] + }, + "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:api-port", + "virtualHosts": [ + { + "name": "public_listener:api-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:api-port" + } + } + ] + } + ] + }, + "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 + } + } + } + ], + "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/multiport-l7-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..594d47c96c55 --- /dev/null +++ b/agent/xdsv2/testdata/listeners/source/multiport-l7-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,309 @@ +{ + "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~admin-port" + ] + }, + "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:admin-port", + "virtualHosts": [ + { + "name": "public_listener:admin-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:admin-port" + } + } + ] + } + ] + }, + "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~api-port" + ] + }, + "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:api-port", + "virtualHosts": [ + { + "name": "public_listener:api-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:api-port" + } + } + ] + } + ] + }, + "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~grpc-port" + ] + }, + "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-port", + "virtualHosts": [ + { + "name": "public_listener:grpc-port", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "local_app:grpc-port" + } + } + ] + } + ] + }, + "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 + } + } + } + ], + "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/output/clusters/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/output/clusters/l4-single-implicit-destination-tproxy.golden deleted file mode 100644 index 611c863c3af9..000000000000 --- a/agent/xdsv2/testdata/output/clusters/l4-single-implicit-destination-tproxy.golden +++ /dev/null @@ -1,56 +0,0 @@ -{ - "versionInfo": "00000001", - "resources": [ - { - "@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" - } - }, - "commonLbConfig": { - "healthyPanicThreshold": {} - }, - "name": "tcp.api-1.default.dc1.internal.foo.consul", - "transportSocket": { - "name": "tls", - "typedConfig": { - "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext", - "commonTlsContext": { - "alpnProtocols": [ - "consul~tcp" - ], - "tlsCertificates": [ - { - "certificateChain": { - "inlineString": "cert1\n" - }, - "privateKey": { - "inlineString": "key1\n" - } - } - ], - "tlsParams": {}, - "validationContext": { - "matchSubjectAltNames": [ - { - "exact": "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" - } - ], - "trustedCa": { - "inlineString": "root1\n" - } - } - }, - "sni": "api-1.default.dc1.internal.foo.consul" - } - }, - "type": "EDS" - } - ], - "typeUrl": "type.googleapis.com/envoy.config.cluster.v3.Cluster", - "nonce": "00000001" -} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/l4-implicit-and-explicit-destinations-tproxy.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-multi-destination.golden b/agent/xdsv2/testdata/routes/destination/l4-multi-destination.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/l4-multi-destination.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/l4-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address.golden b/agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/l4-single-destination-ip-port-bind-address.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address.golden b/agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/l4-single-destination-unix-socket-bind-address.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/l4-single-implicit-destination-tproxy.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "typeUrl": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "nonce": "00000001" +} \ No newline at end of file diff --git a/agent/xdsv2/testdata/routes/destination/mixed-multi-destination.golden b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination.golden new file mode 100644 index 000000000000..28f9669ee371 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/mixed-multi-destination.golden @@ -0,0 +1,67 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "default/local/default/api-1:http:1.1.1.1:1234", + "virtualHosts": [ + { + "name": "default/local/default/api-1:http:1.1.1.1:1234", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/split" + }, + "route": { + "weightedClusters": { + "clusters": [ + { + "name": "http.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "http.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + }, + "timeout": "77s" + } + }, + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "http.api-1.default.dc1.internal.foo.consul", + "timeout": "606s", + "retryPolicy": { + "retryOn": "connect-failure", + "numRetries": 4 + } + } + }, + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "null_route_cluster" + } + } + ] + } + ], + "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/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden new file mode 100644 index 000000000000..c34c2a0602d2 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,53 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "default/local/default/api-app2:http", + "virtualHosts": [ + { + "name": "default/local/default/api-app2:http", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "http.api-app2.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "validateClusters": true + }, + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "default/local/default/api-app:http", + "virtualHosts": [ + { + "name": "default/local/default/api-app:http", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "http.api-app.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "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/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden new file mode 100644 index 000000000000..caa0f6deb000 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden @@ -0,0 +1,30 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "default/local/default/api-app:http", + "virtualHosts": [ + { + "name": "default/local/default/api-app:http", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "http.api-app.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "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/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden new file mode 100644 index 000000000000..caa0f6deb000 --- /dev/null +++ b/agent/xdsv2/testdata/routes/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -0,0 +1,30 @@ +{ + "versionInfo": "00000001", + "resources": [ + { + "@type": "type.googleapis.com/envoy.config.route.v3.RouteConfiguration", + "name": "default/local/default/api-app:http", + "virtualHosts": [ + { + "name": "default/local/default/api-app:http", + "domains": [ + "*" + ], + "routes": [ + { + "match": { + "prefix": "/" + }, + "route": { + "cluster": "http.api-app.default.dc1.internal.foo.consul" + } + } + ] + } + ], + "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/l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "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/l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "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/l4-single-workload-address-without-ports.golden b/agent/xdsv2/testdata/routes/source/l4-single-workload-address-without-ports.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/l4-single-workload-address-without-ports.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "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/l7-expose-paths.golden b/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden new file mode 100644 index 000000000000..68b5239aec9e --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/l7-expose-paths.golden @@ -0,0 +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 new file mode 100644 index 000000000000..97c96f44bb62 --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/local-and-inbound-connections.golden @@ -0,0 +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-l4-multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "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-l4-multiple-workload-addresses-without-ports.golden b/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/multiport-l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "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-l4-workload-with-only-mesh-port.golden b/agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port.golden new file mode 100644 index 000000000000..306f5220e7b9 --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/multiport-l4-workload-with-only-mesh-port.golden @@ -0,0 +1,5 @@ +{ + "versionInfo": "00000001", + "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 new file mode 100644 index 000000000000..3b1a61403ba7 --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +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 new file mode 100644 index 000000000000..7f976890c64b --- /dev/null +++ b/agent/xdsv2/testdata/routes/source/multiport-l7-multiple-workload-addresses-without-ports.golden @@ -0,0 +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/api/.copywrite.hcl b/api/.copywrite.hcl new file mode 100644 index 000000000000..34d99ba25e12 --- /dev/null +++ b/api/.copywrite.hcl @@ -0,0 +1,8 @@ +schema_version = 1 + +project { + license = "MPL-2.0" + copyright_year = 2023 + + header_ignore = [] +} diff --git a/api/config_entry.go b/api/config_entry.go index b59c20fd3007..ffc18a85ed5c 100644 --- a/api/config_entry.go +++ b/api/config_entry.go @@ -341,6 +341,7 @@ type InstanceLevelRateLimits struct { RequestsMaxBurst int `alias:"requests_max_burst"` // Routes is a list of rate limits applied to specific routes. + // For a given request, the first matching route will be applied, if any // Overrides any top-level configuration. Routes []InstanceLevelRouteRateLimits } diff --git a/api/config_entry_rate_limit_ip.go b/api/config_entry_rate_limit_ip.go index 8df7d4c98e77..7af2a2658f2e 100644 --- a/api/config_entry_rate_limit_ip.go +++ b/api/config_entry_rate_limit_ip.go @@ -4,8 +4,8 @@ package api type ReadWriteRatesConfig struct { - ReadRate float64 - WriteRate float64 + ReadRate float64 `alias:"read_rate"` + WriteRate float64 `alias:"write_rate"` } type RateLimitIPConfigEntry struct { @@ -16,8 +16,8 @@ type RateLimitIPConfigEntry struct { Meta map[string]string `json:",omitempty"` // overall limits - ReadRate float64 - WriteRate float64 + ReadRate float64 `alias:"read_rate"` + WriteRate float64 `alias:"write_rate"` //limits specific to a type of call ACL *ReadWriteRatesConfig `json:",omitempty"` // OperationCategoryACL OperationCategory = "ACL" diff --git a/api/config_entry_routes.go b/api/config_entry_routes.go index 1918386576cd..bbaa032d50f6 100644 --- a/api/config_entry_routes.go +++ b/api/config_entry_routes.go @@ -222,10 +222,10 @@ type URLRewrite struct { } type RetryFilter struct { - NumRetries *uint32 + NumRetries uint32 RetryOn []string RetryOnStatusCodes []uint32 - RetryOnConnectFailure *bool + RetryOnConnectFailure bool } type TimeoutFilter struct { diff --git a/api/config_entry_routes_test.go b/api/config_entry_routes_test.go index b878612e907e..0a4f8e38b1b8 100644 --- a/api/config_entry_routes_test.go +++ b/api/config_entry_routes_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/api/config_entry_status_test.go b/api/config_entry_status_test.go index 9c6eaf034c32..ec64c8716407 100644 --- a/api/config_entry_status_test.go +++ b/api/config_entry_status_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import "testing" diff --git a/api/go.mod b/api/go.mod index a9e1b8e353a8..aa6e9a153349 100644 --- a/api/go.mod +++ b/api/go.mod @@ -6,7 +6,7 @@ replace github.com/hashicorp/consul/sdk => ../sdk require ( github.com/google/go-cmp v0.5.9 - github.com/hashicorp/consul/sdk v0.14.1 + github.com/hashicorp/consul/sdk v0.15.0 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-multierror v1.1.1 @@ -39,8 +39,8 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/stretchr/objx v0.5.0 // indirect - golang.org/x/net v0.13.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/sync v0.2.0 // indirect - golang.org/x/sys v0.11.0 // indirect + golang.org/x/sys v0.13.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/api/go.sum b/api/go.sum index 6411c8af5446..bfc3fb8a11fb 100644 --- a/api/go.sum +++ b/api/go.sum @@ -182,8 +182,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= 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-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -211,8 +211,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/api/internal.go b/api/internal.go index dee161a65eb2..b5f400f4b19b 100644 --- a/api/internal.go +++ b/api/internal.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import "context" diff --git a/api/internal_test.go b/api/internal_test.go index ce088f1787d1..ce773d7360f9 100644 --- a/api/internal_test.go +++ b/api/internal_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package api import ( diff --git a/api/operator_audit.go b/api/operator_audit.go index b255d67f4e31..5240d38a70d7 100644 --- a/api/operator_audit.go +++ b/api/operator_audit.go @@ -1,5 +1,5 @@ // Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 +// SPDX-License-Identifier: MPL-2.0 // The /v1/operator/audit-hash endpoint is available only in Consul Enterprise and // interact with its audit logging subsystem. diff --git a/build-support/docker/Build-Go.dockerfile b/build-support/docker/Build-Go.dockerfile index c0186842fb76..884bc4894af3 100644 --- a/build-support/docker/Build-Go.dockerfile +++ b/build-support/docker/Build-Go.dockerfile @@ -1,7 +1,7 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: BUSL-1.1 -ARG GOLANG_VERSION=1.20.8 +ARG GOLANG_VERSION=1.20.10 FROM golang:${GOLANG_VERSION} WORKDIR /consul diff --git a/build-support/docker/Build-UI.dockerfile b/build-support/docker/Build-UI.dockerfile index 9d646fb6ea69..01e8c8254b08 100644 --- a/build-support/docker/Build-UI.dockerfile +++ b/build-support/docker/Build-UI.dockerfile @@ -1,10 +1,11 @@ # Copyright (c) HashiCorp, Inc. # SPDX-License-Identifier: BUSL-1.1 -FROM docker.mirror.hashicorp.services/circleci/node:16-browsers +FROM docker.mirror.hashicorp.services/node:18-alpine USER root +RUN apk update && apk add make RUN mkdir /consul-src WORKDIR /consul-src CMD make dist-docker diff --git a/build-support/docker/Consul-Dev-Multiarch.dockerfile b/build-support/docker/Consul-Dev-Multiarch.dockerfile index e35a98d5f890..075c5607a722 100644 --- a/build-support/docker/Consul-Dev-Multiarch.dockerfile +++ b/build-support/docker/Consul-Dev-Multiarch.dockerfile @@ -2,7 +2,7 @@ # SPDX-License-Identifier: BUSL-1.1 ARG CONSUL_IMAGE_VERSION=latest -FROM hashicorp/consul:${CONSUL_IMAGE_VERSION} +FROM docker.mirror.hashicorp.services/hashicorp/consul:${CONSUL_IMAGE_VERSION} RUN apk update && apk add iptables ARG TARGETARCH COPY linux_${TARGETARCH}/consul /bin/consul diff --git a/build-support/docker/Consul-Dev.dockerfile b/build-support/docker/Consul-Dev.dockerfile index 12f014969ab5..6586f09bd016 100644 --- a/build-support/docker/Consul-Dev.dockerfile +++ b/build-support/docker/Consul-Dev.dockerfile @@ -2,6 +2,6 @@ # SPDX-License-Identifier: BUSL-1.1 ARG CONSUL_IMAGE_VERSION=latest -FROM hashicorp/consul:${CONSUL_IMAGE_VERSION} +FROM docker.mirror.hashicorp.services/hashicorp/consul:${CONSUL_IMAGE_VERSION} RUN apk update && apk add iptables COPY consul /bin/consul diff --git a/build-support/scripts/copywrite-exceptions.sh b/build-support/scripts/copywrite-exceptions.sh new file mode 100755 index 000000000000..f6ca45626cf2 --- /dev/null +++ b/build-support/scripts/copywrite-exceptions.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +# Used as a stopgap for copywrite bot in MPL-licensed subdirs, detects BUSL licensed +# headers and deletes them, then runs the copywrite bot to utilize local subdir config +# to inject correct headers. + +find . -type f -name '*.go' | while read line; do + if grep "SPDX-License-Identifier: BUSL-1.1" $line; then + sed -i '/SPDX-License-Identifier: BUSL-1.1/d' $line + sed -i '/Copyright (c) HashiCorp, Inc./d' $line + fi +done + +copywrite headers diff --git a/command/acl/role/create/role_create.go b/command/acl/role/create/role_create.go index b93d25548d28..c6bc7330a915 100644 --- a/command/acl/role/create/role_create.go +++ b/command/acl/role/create/role_create.go @@ -94,6 +94,13 @@ func (c *cmd) Run(args []string) int { return 1 } + if len(c.templatedPolicyFile) != 0 && len(c.templatedPolicy) != 0 { + c.UI.Error("Cannot combine the use of templated-policy flag with templated-policy-file. " + + "To create a role with a single templated policy and simple use case, use -templated-policy. " + + "For multiple templated policies and more complicated use cases, use -templated-policy-file") + return 1 + } + client, err := c.http.APIClient() if err != nil { c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) diff --git a/command/acl/role/create/role_create_test.go b/command/acl/role/create/role_create_test.go index 7094a76e6cc7..55aebc13fac2 100644 --- a/command/acl/role/create/role_create_test.go +++ b/command/acl/role/create/role_create_test.go @@ -115,6 +115,22 @@ func TestRoleCreateCommand_Pretty(t *testing.T) { require.Len(t, role.NodeIdentities, 1) }) + + t.Run("prevent templated-policy and templated-policy-file simultaneous use", func(t *testing.T) { + ui := cli.NewMockUi() + cmd := New(ui) + + code := cmd.Run([]string{ + "-http-addr=" + a.HTTPAddr(), + "-token=root", + "-name=role-with-node-identity", + "-templated-policy=builtin/node", + "-var=name:" + a.Config.NodeName, + "-templated-policy-file=test.hcl", + }) + require.Equal(t, 1, code) + require.Contains(t, ui.ErrorWriter.String(), "Cannot combine the use of templated-policy flag with templated-policy-file.") + }) } func TestRoleCreateCommand_JSON(t *testing.T) { diff --git a/command/acl/token/create/token_create.go b/command/acl/token/create/token_create.go index bb6e52416780..b7a7b9eefa67 100644 --- a/command/acl/token/create/token_create.go +++ b/command/acl/token/create/token_create.go @@ -105,6 +105,13 @@ func (c *cmd) Run(args []string) int { return 1 } + if len(c.templatedPolicyFile) != 0 && len(c.templatedPolicy) != 0 { + c.UI.Error("Cannot combine the use of templated-policy flag with templated-policy-file. " + + "To create a token with a single templated policy and simple use case, use -templated-policy. " + + "For multiple templated policies and more complicated use cases, use -templated-policy-file") + return 1 + } + client, err := c.http.APIClient() if err != nil { c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) diff --git a/command/acl/token/create/token_create_test.go b/command/acl/token/create/token_create_test.go index 90471b5a5b2a..55ced9a3d17e 100644 --- a/command/acl/token/create/token_create_test.go +++ b/command/acl/token/create/token_create_test.go @@ -128,6 +128,21 @@ func TestTokenCreateCommand_Pretty(t *testing.T) { require.Equal(t, a.Config.NodeName, nodes[0].Node) }) + t.Run("prevent templated-policy and templated-policy-file simultaneous use", func(t *testing.T) { + ui := cli.NewMockUi() + cmd := New(ui) + + code := cmd.Run(append([]string{ + "-http-addr=" + a.HTTPAddr(), + "-token=root", + "-templated-policy=builtin/node", + "-var=name:" + a.Config.NodeName, + "-templated-policy-file=test.hcl", + }, "-format=json")) + require.Equal(t, 1, code) + require.Contains(t, ui.ErrorWriter.String(), "Cannot combine the use of templated-policy flag with templated-policy-file.") + }) + // create with accessor and secret t.Run("predefined-ids", func(t *testing.T) { token := run(t, []string{ diff --git a/command/resource/delete/delete.go b/command/resource/delete/delete.go index 2679951da8b1..06421d6d1e2d 100644 --- a/command/resource/delete/delete.go +++ b/command/resource/delete/delete.go @@ -84,10 +84,6 @@ func (c *cmd) Run(args []string) int { return 1 } } else { - if len(args) < 2 { - c.UI.Error("Incorrect argument format: Must specify two arguments: resource type and resource name") - return 1 - } var err error gvk, resourceName, err = resource.GetTypeAndResourceName(args) if err != nil { diff --git a/command/resource/delete/delete_test.go b/command/resource/delete/delete_test.go index f888bb3c8fd5..7454455c941e 100644 --- a/command/resource/delete/delete_test.go +++ b/command/resource/delete/delete_test.go @@ -67,7 +67,7 @@ func TestResourceDeleteInvalidArgs(t *testing.T) { "invalid resource type format": { args: []string{"a.", "name", "-namespace", "default"}, expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must include resource type argument in group.verion.kind format"), + expectedErr: errors.New("Must provide resource type argument with either in group.verion.kind format or its shorthand name"), }, } diff --git a/command/resource/helper.go b/command/resource/helper.go index 417144ac7896..221a018599a7 100644 --- a/command/resource/helper.go +++ b/command/resource/helper.go @@ -96,21 +96,7 @@ func parseJson(js string) (*pbresource.Resource, error) { } func ParseResourceFromFile(filePath string) (*pbresource.Resource, error) { - data, err := helpers.LoadDataSourceNoRaw(filePath, nil) - if err != nil { - return nil, fmt.Errorf("Failed to load data: %v", err) - } - var parsedResource *pbresource.Resource - if isHCL([]byte(data)) { - parsedResource, err = resourcehcl.Unmarshal([]byte(data), consul.NewTypeRegistry()) - } else { - parsedResource, err = parseJson(data) - } - if err != nil { - return nil, fmt.Errorf("Failed to decode resource from input file: %v", err) - } - - return parsedResource, nil + return ParseResourceInput(filePath, nil) } // this is an inlined variant of hcl.lexMode() @@ -165,23 +151,17 @@ func ParseInputParams(inputArgs []string, flags *flag.FlagSet) error { } func GetTypeAndResourceName(args []string) (gvk *GVK, resourceName string, e error) { + if len(args) < 2 { + return nil, "", fmt.Errorf("Must specify two arguments: resource type and resource name") + } // it has to be resource name after the type if strings.HasPrefix(args[1], "-") { return nil, "", fmt.Errorf("Must provide resource name right after type") } + resourceName = args[1] - s := strings.Split(args[0], ".") - if len(s) != 3 { - return nil, "", fmt.Errorf("Must include resource type argument in group.verion.kind format") - } - - gvk = &GVK{ - Group: s[0], - Version: s[1], - Kind: s[2], - } + gvk, e = inferGVKFromResourceType(args[0]) - resourceName = args[1] return } @@ -282,3 +262,54 @@ func (resource *Resource) List(gvk *GVK, q *client.QueryOptions) (*ListResponse, return out, nil } + +func inferGVKFromResourceType(resourceType string) (*GVK, error) { + s := strings.Split(resourceType, ".") + switch length := len(s); { + // only kind is provided + case length == 1: + kindToGVKMap := BuildKindToGVKMap() + kind := strings.ToLower(s[0]) + switch len(kindToGVKMap[kind]) { + // no g.v.k is found + case 0: + return nil, fmt.Errorf("The shorthand name does not map to any existing resource type, please check `consul api-resources`") + // only one is found + case 1: + // infer gvk from resource kind + gvkSplit := strings.Split(kindToGVKMap[kind][0], ".") + return &GVK{ + Group: gvkSplit[0], + Version: gvkSplit[1], + Kind: gvkSplit[2], + }, nil + // it alerts error if any conflict is found + default: + return nil, fmt.Errorf("The shorthand name has conflicts %v, please use the full name", kindToGVKMap[s[0]]) + } + case length == 3: + return &GVK{ + Group: s[0], + Version: s[1], + Kind: s[2], + }, nil + default: + return nil, fmt.Errorf("Must provide resource type argument with either in group.verion.kind format or its shorthand name") + } +} + +func BuildKindToGVKMap() map[string][]string { + // this use the local copy of registration to build map + typeRegistry := consul.NewTypeRegistry() + kindToGVKMap := map[string][]string{} + for _, r := range typeRegistry.Types() { + gvkString := fmt.Sprintf("%s.%s.%s", r.Type.Group, r.Type.GroupVersion, r.Type.Kind) + kindKey := strings.ToLower(r.Type.Kind) + if len(kindToGVKMap[kindKey]) == 0 { + kindToGVKMap[kindKey] = []string{gvkString} + } else { + kindToGVKMap[kindKey] = append(kindToGVKMap[kindKey], gvkString) + } + } + return kindToGVKMap +} diff --git a/command/resource/read/read_test.go b/command/resource/read/read_test.go index 766f86b02cc1..a293a9faf5e2 100644 --- a/command/resource/read/read_test.go +++ b/command/resource/read/read_test.go @@ -67,7 +67,7 @@ func TestResourceReadInvalidArgs(t *testing.T) { "invalid resource type format": { args: []string{"a.", "name", "-namespace", "default"}, expectedCode: 1, - expectedErr: errors.New("Incorrect argument format: Must include resource type argument in group.verion.kind format"), + expectedErr: errors.New("Incorrect argument format: Must provide resource type argument with either in group.verion.kind format or its shorthand name"), }, } diff --git a/command/resource/testdata/nested_data.hcl b/command/resource/testdata/nested_data.hcl index aab8aa401ee9..b62875c732b4 100644 --- a/command/resource/testdata/nested_data.hcl +++ b/command/resource/testdata/nested_data.hcl @@ -21,6 +21,7 @@ Data { DestinationPort = "tcp" IpPort = { + Ip = "127.0.0.1" Port = 1234 } } diff --git a/command/services/register/register_test.go b/command/services/register/register_test.go index 24d5f4fb87ea..8b4d94328a12 100644 --- a/command/services/register/register_test.go +++ b/command/services/register/register_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/hashicorp/consul/agent" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil" "github.com/mitchellh/cli" "github.com/stretchr/testify/require" @@ -75,7 +76,7 @@ func TestCommand_File(t *testing.T) { ui := cli.NewMockUi() c := New(ui) - contents := `{ "Service": { "Name": "web" } }` + contents := `{ "Service": { "Name": "web", "Locality": { "Region": "us-east-1", "Zone": "us-east-1a" } } }` f := testFile(t, "json") defer os.Remove(f.Name()) if _, err := f.WriteString(contents); err != nil { @@ -93,8 +94,11 @@ func TestCommand_File(t *testing.T) { require.NoError(t, err) require.Len(t, svcs, 1) - svc := svcs["web"] - require.NotNil(t, svc) + require.NotNil(t, svcs["web"]) + + svc, _, err := client.Agent().Service("web", nil) + require.NoError(t, err) + require.Equal(t, &api.Locality{Region: "us-east-1", Zone: "us-east-1a"}, svc.Locality) } func TestCommand_Flags(t *testing.T) { diff --git a/envoyextensions/go.mod b/envoyextensions/go.mod index 4d4301841ea3..f6f1b1b186fc 100644 --- a/envoyextensions/go.mod +++ b/envoyextensions/go.mod @@ -10,8 +10,8 @@ replace ( require ( github.com/envoyproxy/go-control-plane v0.11.0 github.com/google/go-cmp v0.5.9 - github.com/hashicorp/consul/api v1.24.0 - github.com/hashicorp/consul/sdk v0.14.1 + github.com/hashicorp/consul/api v1.26.1 + github.com/hashicorp/consul/sdk v0.15.0 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-version v1.2.1 @@ -41,7 +41,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/sys v0.11.0 // indirect + golang.org/x/sys v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/envoyextensions/go.sum b/envoyextensions/go.sum index de21ca6c0b42..b611aa2308ee 100644 --- a/envoyextensions/go.sum +++ b/envoyextensions/go.sum @@ -200,7 +200,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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= @@ -229,8 +229,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= diff --git a/envoyextensions/xdscommon/envoy_versioning_test.go b/envoyextensions/xdscommon/envoy_versioning_test.go index bc02e9c4aadc..925e2fa5378f 100644 --- a/envoyextensions/xdscommon/envoy_versioning_test.go +++ b/envoyextensions/xdscommon/envoy_versioning_test.go @@ -151,10 +151,10 @@ func TestDetermineSupportedProxyFeaturesFromString(t *testing.T) { } */ for _, v := range []string{ - "1.24.0", "1.24.1", "1.24.2", "1.24.3", "1.24.4", "1.24.5", "1.24.6", "1.24.7", "1.24.8", "1.24.9", "1.24.10", - "1.25.0", "1.25.1", "1.25.2", "1.25.3", "1.25.4", "1.25.5", "1.25.6", "1.25.7", "1.25.8", "1.25.9", - "1.26.0", "1.26.1", "1.26.2", "1.26.3", "1.26.4", - "1.27.0", + "1.24.0", "1.24.1", "1.24.2", "1.24.3", "1.24.4", "1.24.5", "1.24.6", "1.24.7", "1.24.8", "1.24.9", "1.24.10", "1.24.11", "1.24.12", + "1.25.0", "1.25.1", "1.25.2", "1.25.3", "1.25.4", "1.25.5", "1.25.6", "1.25.7", "1.25.8", "1.25.9", "1.25.10", "1.25.11", + "1.26.0", "1.26.1", "1.26.2", "1.26.3", "1.26.4", "1.26.5", "1.26.6", + "1.27.0", "1.27.1", "1.27.2", } { cases[v] = testcase{expect: SupportedProxyFeatures{}} } diff --git a/envoyextensions/xdscommon/proxysupport.go b/envoyextensions/xdscommon/proxysupport.go index 764d967616f6..9e487e1867e2 100644 --- a/envoyextensions/xdscommon/proxysupport.go +++ b/envoyextensions/xdscommon/proxysupport.go @@ -12,10 +12,10 @@ import "strings" // // see: https://www.consul.io/docs/connect/proxies/envoy#supported-versions var EnvoyVersions = []string{ - "1.27.0", - "1.26.4", - "1.25.9", - "1.24.10", + "1.27.2", + "1.26.6", + "1.25.11", + "1.24.12", } // UnsupportedEnvoyVersions lists any unsupported Envoy versions (mainly minor versions) that fall diff --git a/fixup_acl_move.sh b/fixup_acl_move.sh deleted file mode 100644 index ac57c8c7e933..000000000000 --- a/fixup_acl_move.sh +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (c) HashiCorp, Inc. -# SPDX-License-Identifier: BUSL-1.1 - - -GOIMPORTS=~/go/bin/goimports - -CHANGED=(EnterpriseMeta PartitionOrDefault IsDefaultPartition NamespaceOrDefault NewEnterpriseMetaWithPartition EqualPartitions) - -DIRS=(agent command proto) - -for dir in "${DIRS[@]}" - do - echo "CD to $dir" - pushd $dir - for s in "${CHANGED[@]}" - do - REWRITE='structs.'$s' -> acl.'$s - echo "REPL $REWRITE" - gofmt -w -r="$REWRITE" . - done - popd -done - -find . -name \*.go | xargs fgrep 'acl.' -l | xargs $GOIMPORTS -local "github.com/hashicorp/consul" -w - -make --always-make proto -make go-mod-tidy diff --git a/go.mod b/go.mod index b89b5d420c24..48c59e089101 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/coredns/coredns v1.10.1 github.com/coreos/go-oidc v2.1.0+incompatible github.com/docker/go-connections v0.4.0 - github.com/envoyproxy/go-control-plane v0.11.0 + github.com/envoyproxy/go-control-plane v0.11.1 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e github.com/fatih/color v1.14.1 github.com/fsnotify/fsnotify v1.6.0 @@ -38,11 +38,11 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 github.com/hashicorp/consul-net-rpc v0.0.0-20221205195236-156cfab66a69 - github.com/hashicorp/consul/api v1.24.0 - github.com/hashicorp/consul/envoyextensions v0.4.1 - github.com/hashicorp/consul/proto-public v0.4.1 - github.com/hashicorp/consul/sdk v0.14.1 - github.com/hashicorp/consul/troubleshoot v0.3.1 + github.com/hashicorp/consul/api v1.26.1 + github.com/hashicorp/consul/envoyextensions v0.5.1 + github.com/hashicorp/consul/proto-public v0.5.1 + github.com/hashicorp/consul/sdk v0.15.0 + github.com/hashicorp/consul/troubleshoot v0.4.1 github.com/hashicorp/go-bexpr v0.1.2 github.com/hashicorp/go-checkpoint v0.5.0 github.com/hashicorp/go-cleanhttp v0.5.2 @@ -71,7 +71,7 @@ require ( github.com/hashicorp/raft v1.5.0 github.com/hashicorp/raft-autopilot v0.1.6 github.com/hashicorp/raft-boltdb/v2 v2.2.2 - github.com/hashicorp/raft-wal v0.3.0 + github.com/hashicorp/raft-wal v0.4.1 github.com/hashicorp/serf v0.10.1 github.com/hashicorp/vault-plugin-auth-alicloud v0.14.0 github.com/hashicorp/vault/api v1.8.3 @@ -109,26 +109,25 @@ require ( go.opentelemetry.io/otel/sdk/metric v0.39.0 go.opentelemetry.io/proto/otlp v0.19.0 go.uber.org/goleak v1.1.10 - golang.org/x/crypto v0.12.0 + golang.org/x/crypto v0.14.0 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 - golang.org/x/net v0.14.0 - golang.org/x/oauth2 v0.6.0 + golang.org/x/net v0.17.0 + golang.org/x/oauth2 v0.7.0 golang.org/x/sync v0.3.0 - golang.org/x/sys v0.11.0 + golang.org/x/sys v0.13.0 golang.org/x/time v0.3.0 - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 - google.golang.org/grpc v1.55.0 + google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e + google.golang.org/grpc v1.56.3 google.golang.org/protobuf v1.30.0 gopkg.in/square/go-jose.v2 v2.5.1 gotest.tools/v3 v3.4.0 k8s.io/api v0.26.2 k8s.io/apimachinery v0.26.2 k8s.io/client-go v0.26.2 - k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 ) require ( - cloud.google.com/go/compute v1.19.0 // indirect + cloud.google.com/go/compute v1.19.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v0.13.0 // indirect github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect @@ -159,7 +158,7 @@ require ( 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-20230310173818-32f1caf87195 // indirect + github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/coreos/etcd v3.3.27+incompatible // indirect github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect github.com/coreos/pkg v0.0.0-20220810130054-c7d1c02cb6cf // indirect @@ -169,7 +168,7 @@ require ( github.com/digitalocean/godo v1.10.0 // indirect github.com/dimchansky/utfbom v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect - github.com/envoyproxy/protoc-gen-validate v0.10.0 // indirect + github.com/envoyproxy/protoc-gen-validate v1.0.1 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.2.6 // indirect @@ -233,7 +232,7 @@ require ( github.com/posener/complete v1.2.3 // indirect github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect - github.com/prometheus/client_model v0.3.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/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect @@ -262,11 +261,13 @@ require ( go.uber.org/atomic v1.9.0 // indirect golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/term v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect google.golang.org/api v0.114.0 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect @@ -275,6 +276,7 @@ require ( gopkg.in/yaml.v3 v3.0.1 // 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 diff --git a/go.sum b/go.sum index a809cbba8070..3598121de6f4 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,8 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.19.0 h1:+9zda3WGgW1ZSTlVppLCYFIr48Pa35q1uG2N1itbCEQ= -cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= 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= @@ -183,8 +183,8 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH 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-20230310173818-32f1caf87195 h1:58f1tJ1ra+zFINPlwLWvQsR9CzAKt2e+EWV2yX9oXQ4= -github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/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/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coredns/coredns v1.10.1 h1:6OyL7tcvYxeNHONj5iQlVM2GXBzAOq57L3/LUKP1DbA= github.com/coredns/coredns v1.10.1/go.mod h1:oGgoY6cRrdJzKgNrsT30Hztu7/MutSHCYwqGDWngXCc= @@ -240,13 +240,13 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.11.0 h1:jtLewhRR2vMRNnq2ZZUoCjUlgut+Y0+sDDWPOfwOi1o= -github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/go-control-plane 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/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e h1:g8euodkL4GdSpVAjfzhssb07KgVmOUqyF4QOmwFumTs= github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e/go.mod h1:/NGEcKqwNq3HAS2vCqHfsPx9sJZbkiNQ6dGx9gTE/NA= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.10.0 h1:oIfnZFdC0YhpNNEX+SuIqko4cqqVZeN9IGTrhZje83Y= -github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +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.2.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= @@ -595,8 +595,8 @@ github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qR 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.3.0 h1:Mi6RPoRbsxIIYZryI+bSTXHD97Ua6rIYO51ibYV9bkY= -github.com/hashicorp/raft-wal v0.3.0/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= +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= @@ -832,8 +832,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: 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.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +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-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1037,8 +1037,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +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= @@ -1133,8 +1133,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx 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.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +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= @@ -1151,8 +1151,8 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ 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.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= -golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= 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= @@ -1251,13 +1251,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.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.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +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-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1269,8 +1269,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +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= @@ -1445,8 +1445,12 @@ google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEc 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-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e h1:AZX1ra8YbFMSb7+1pI8S9v4rrgRR7jU1FmuFSSjTVcQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e h1:NumxXLPfHSndr3wBBdeKiVHjGVFzi9RX2HwwQke94iY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= 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= @@ -1476,8 +1480,8 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD 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.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= 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= diff --git a/internal/auth/internal/types/computed_traffic_permissions.go b/internal/auth/internal/types/computed_traffic_permissions.go index 0ba88427233b..0a32e13d2926 100644 --- a/internal/auth/internal/types/computed_traffic_permissions.go +++ b/internal/auth/internal/types/computed_traffic_permissions.go @@ -19,7 +19,7 @@ func RegisterComputedTrafficPermission(r resource.Registry) { ACLs: &resource.ACLHooks{ Read: aclReadHookComputedTrafficPermissions, Write: aclWriteHookComputedTrafficPermissions, - List: aclListHookComputedTrafficPermissions, + List: resource.NoOpACLListHook, }, Validate: ValidateComputedTrafficPermissions, Scope: resource.ScopeNamespace, @@ -71,9 +71,3 @@ func aclReadHookComputedTrafficPermissions(authorizer acl.Authorizer, authzConte func aclWriteHookComputedTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { return authorizer.ToAllowAuthorizer().TrafficPermissionsWriteAllowed(res.Id.Name, authzContext) } - -func aclListHookComputedTrafficPermissions(_ acl.Authorizer, _ *acl.AuthorizerContext) error { - // No-op List permission as we want to default to filtering resources - // from the list using the Read enforcement - return nil -} diff --git a/internal/auth/internal/types/errors.go b/internal/auth/internal/types/errors.go index b79d7a3b98e9..b11fac630476 100644 --- a/internal/auth/internal/types/errors.go +++ b/internal/auth/internal/types/errors.go @@ -12,4 +12,5 @@ var ( errSourceExcludes = errors.New("must be defined on wildcard sources") errInvalidPrefixValues = errors.New("prefix values, regex values, and explicit names must not combined") ErrWildcardNotSupported = errors.New("traffic permissions without explicit destinations are not yet supported") + ErrL7NotSupported = errors.New("traffic permissions with L7 rules are not yet supported") ) diff --git a/internal/auth/internal/types/traffic_permissions.go b/internal/auth/internal/types/traffic_permissions.go index fb1de7acff90..84a30a46e2f6 100644 --- a/internal/auth/internal/types/traffic_permissions.go +++ b/internal/auth/internal/types/traffic_permissions.go @@ -19,7 +19,7 @@ func RegisterTrafficPermissions(r resource.Registry) { ACLs: &resource.ACLHooks{ Read: aclReadHookTrafficPermissions, Write: aclWriteHookTrafficPermissions, - List: aclListHookTrafficPermissions, + List: resource.NoOpACLListHook, }, Validate: ValidateTrafficPermissions, Mutate: MutateTrafficPermissions, @@ -227,6 +227,13 @@ func validatePermission(p *pbauth.Permission, wrapErr func(error) error) error { Wrapped: err, }) } + // TODO: remove this when L7 traffic permissions are implemented + if len(dest.PathExact) > 0 || len(dest.PathPrefix) > 0 || len(dest.PathRegex) > 0 || len(dest.Methods) > 0 || dest.Header != nil { + merr = multierror.Append(merr, wrapDestRuleErr(resource.ErrInvalidListElement{ + Name: "destination_rule", + Wrapped: ErrL7NotSupported, + })) + } if (len(dest.PathExact) > 0 && len(dest.PathPrefix) > 0) || (len(dest.PathRegex) > 0 && len(dest.PathExact) > 0) || (len(dest.PathRegex) > 0 && len(dest.PathPrefix) > 0) { @@ -244,6 +251,13 @@ func validatePermission(p *pbauth.Permission, wrapErr func(error) error) error { Wrapped: err, }) } + // TODO: remove this when L7 traffic permissions are implemented + if len(excl.PathExact) > 0 || len(excl.PathPrefix) > 0 || len(excl.PathRegex) > 0 || len(excl.Methods) > 0 || excl.Header != nil { + merr = multierror.Append(merr, wrapDestRuleErr(resource.ErrInvalidListElement{ + Name: "exclude_permission_rules", + Wrapped: ErrL7NotSupported, + })) + } if (len(excl.PathExact) > 0 && len(excl.PathPrefix) > 0) || (len(excl.PathRegex) > 0 && len(excl.PathExact) > 0) || (len(excl.PathRegex) > 0 && len(excl.PathPrefix) > 0) { @@ -273,7 +287,7 @@ func isLocalPeer(p string) bool { func aclReadHookTrafficPermissions(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { if res == nil { - return resource.ErrNeedData + return resource.ErrNeedResource } return authorizeDestination(res, func(dest string) error { return authorizer.ToAllowAuthorizer().TrafficPermissionsReadAllowed(dest, authzContext) @@ -286,12 +300,6 @@ func aclWriteHookTrafficPermissions(authorizer acl.Authorizer, authzContext *acl }) } -func aclListHookTrafficPermissions(_ acl.Authorizer, _ *acl.AuthorizerContext) error { - // No-op List permission as we want to default to filtering resources - // from the list using the Read enforcement - return nil -} - func authorizeDestination(res *pbresource.Resource, intentionAllowed func(string) error) error { tp, err := resource.Decode[*pbauth.TrafficPermissions](res) if err != nil { diff --git a/internal/auth/internal/types/traffic_permissions_test.go b/internal/auth/internal/types/traffic_permissions_test.go index 0948d240b699..94fb165c3b8b 100644 --- a/internal/auth/internal/types/traffic_permissions_test.go +++ b/internal/auth/internal/types/traffic_permissions_test.go @@ -65,10 +65,46 @@ func TestValidateTrafficPermissions(t *testing.T) { }, "no-destination": { tp: &pbauth.TrafficPermissions{ + Action: pbauth.Action_ACTION_ALLOW, + Permissions: nil, + }, + expectErr: `invalid "data.destination" field: cannot be empty`, + }, + "source-tenancy": { + tp: &pbauth.TrafficPermissions{ + Destination: &pbauth.Destination{ + IdentityName: "w1", + }, + Action: pbauth.Action_ACTION_ALLOW, + Permissions: []*pbauth.Permission{ + { + Sources: []*pbauth.Source{ + { + Partition: "ap1", + Peer: "cl1", + SamenessGroup: "sg1", + }, + }, + DestinationRules: nil, + }, + }, + }, + expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "sources": invalid element at index 0 of list "source": permissions sources may not specify partitions, peers, and sameness_groups together`, + }, + // TODO: remove when L7 traffic permissions are implemented + "l7-fields-path": { + tp: &pbauth.TrafficPermissions{ + Destination: &pbauth.Destination{ + IdentityName: "w1", + }, Action: pbauth.Action_ACTION_ALLOW, Permissions: []*pbauth.Permission{ { - Sources: nil, + Sources: []*pbauth.Source{ + { + Partition: "ap1", + }, + }, DestinationRules: []*pbauth.DestinationRule{ { PathExact: "wi2", @@ -77,9 +113,9 @@ func TestValidateTrafficPermissions(t *testing.T) { }, }, }, - expectErr: `invalid "data.destination" field: cannot be empty`, + expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "destination_rules": invalid element at index 0 of list "destination_rule": traffic permissions with L7 rules are not yet supported`, }, - "source-tenancy": { + "l7-fields-methods": { tp: &pbauth.TrafficPermissions{ Destination: &pbauth.Destination{ IdentityName: "w1", @@ -89,16 +125,41 @@ func TestValidateTrafficPermissions(t *testing.T) { { Sources: []*pbauth.Source{ { - Partition: "ap1", - Peer: "cl1", - SamenessGroup: "sg1", + Partition: "ap1", + }, + }, + DestinationRules: []*pbauth.DestinationRule{ + { + Methods: []string{"PUT"}, }, }, - DestinationRules: nil, }, }, }, - expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "sources": invalid element at index 0 of list "source": permissions sources may not specify partitions, peers, and sameness_groups together`, + expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "destination_rules": invalid element at index 0 of list "destination_rule": traffic permissions with L7 rules are not yet supported`, + }, + "l7-fields-header": { + tp: &pbauth.TrafficPermissions{ + Destination: &pbauth.Destination{ + IdentityName: "w1", + }, + Action: pbauth.Action_ACTION_ALLOW, + Permissions: []*pbauth.Permission{ + { + Sources: []*pbauth.Source{ + { + Partition: "ap1", + }, + }, + DestinationRules: []*pbauth.DestinationRule{ + { + Header: &pbauth.DestinationRuleHeader{Name: "foo"}, + }, + }, + }, + }, + }, + expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "destination_rules": invalid element at index 0 of list "destination_rule": traffic permissions with L7 rules are not yet supported`, }, } diff --git a/internal/auth/internal/types/workload_identity.go b/internal/auth/internal/types/workload_identity.go index 5379d256ba4f..17334e66099e 100644 --- a/internal/auth/internal/types/workload_identity.go +++ b/internal/auth/internal/types/workload_identity.go @@ -18,7 +18,7 @@ func RegisterWorkloadIdentity(r resource.Registry) { ACLs: &resource.ACLHooks{ Read: aclReadHookWorkloadIdentity, Write: aclWriteHookWorkloadIdentity, - List: aclListHookWorkloadIdentity, + List: resource.NoOpACLListHook, }, Validate: nil, }) @@ -36,7 +36,7 @@ func aclReadHookWorkloadIdentity( if res != nil { return authorizer.ToAllowAuthorizer().IdentityReadAllowed(res.Id.Name, authzCtx) } - return resource.ErrNeedData + return resource.ErrNeedResource } func aclWriteHookWorkloadIdentity( @@ -44,13 +44,7 @@ func aclWriteHookWorkloadIdentity( authzCtx *acl.AuthorizerContext, res *pbresource.Resource) error { if res == nil { - return resource.ErrNeedData + return resource.ErrNeedResource } return authorizer.ToAllowAuthorizer().IdentityWriteAllowed(res.Id.Name, authzCtx) } - -func aclListHookWorkloadIdentity(authorizer acl.Authorizer, context *acl.AuthorizerContext) error { - // No-op List permission as we want to default to filtering resources - // from the list using the Read enforcement - return nil -} diff --git a/internal/auth/internal/types/workload_identity_test.go b/internal/auth/internal/types/workload_identity_test.go index 1ca59952ecee..8dfb22bc74a2 100644 --- a/internal/auth/internal/types/workload_identity_test.go +++ b/internal/auth/internal/types/workload_identity_test.go @@ -82,8 +82,8 @@ func TestWorkloadIdentityACLs(t *testing.T) { checkF(t, tc.listOK, err) }) t.Run("errors", func(t *testing.T) { - require.ErrorIs(t, reg.ACLs.Read(authz, &acl.AuthorizerContext{}, nil, nil), resource.ErrNeedData) - require.ErrorIs(t, reg.ACLs.Write(authz, &acl.AuthorizerContext{}, nil), resource.ErrNeedData) + require.ErrorIs(t, reg.ACLs.Read(authz, &acl.AuthorizerContext{}, nil, nil), resource.ErrNeedResource) + require.ErrorIs(t, reg.ACLs.Write(authz, &acl.AuthorizerContext{}, nil), resource.ErrNeedResource) }) } diff --git a/internal/catalog/catalogtest/helpers/acl_hooks_test_helpers.go b/internal/catalog/catalogtest/helpers/acl_hooks_test_helpers.go new file mode 100644 index 000000000000..097647ed08d1 --- /dev/null +++ b/internal/catalog/catalogtest/helpers/acl_hooks_test_helpers.go @@ -0,0 +1,21 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package helpers + +import ( + "testing" + + "github.com/hashicorp/consul/internal/catalog" + "github.com/hashicorp/consul/internal/catalog/internal/testhelpers" + "github.com/hashicorp/consul/internal/resource" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" +) + +func RunWorkloadSelectingTypeACLsTests[T catalog.WorkloadSelecting](t *testing.T, typ *pbresource.Type, + getData func(selector *pbcatalog.WorkloadSelector) T, + registerFunc func(registry resource.Registry), +) { + testhelpers.RunWorkloadSelectingTypeACLsTests[T](t, typ, getData, registerFunc) +} diff --git a/internal/catalog/exports.go b/internal/catalog/exports.go index c4e70ffbefe1..3c43643de419 100644 --- a/internal/catalog/exports.go +++ b/internal/catalog/exports.go @@ -48,6 +48,12 @@ var ( FailoverStatusConditionAcceptedUsingMeshDestinationPortReason = failover.UsingMeshDestinationPortReason ) +type WorkloadSelecting = types.WorkloadSelecting + +func ACLHooksForWorkloadSelectingType[T WorkloadSelecting]() *resource.ACLHooks { + return types.ACLHooksForWorkloadSelectingType[T]() +} + // RegisterTypes adds all resource types within the "catalog" API group // to the given type registry func RegisterTypes(r resource.Registry) { @@ -110,3 +116,15 @@ func ValidateLocalServiceRefNoSection(ref *pbresource.Reference, wrapErr func(er func ValidateSelector(sel *pbcatalog.WorkloadSelector, allowEmpty bool) error { return types.ValidateSelector(sel, allowEmpty) } + +func ValidatePortName(name string) error { + return types.ValidatePortName(name) +} + +func IsValidUnixSocketPath(host string) bool { + return types.IsValidUnixSocketPath(host) +} + +func ValidateProtocol(protocol pbcatalog.Protocol) error { + return types.ValidateProtocol(protocol) +} diff --git a/internal/catalog/internal/controllers/nodehealth/controller_test.go b/internal/catalog/internal/controllers/nodehealth/controller_test.go index 30989b479b0f..b21c52e521f8 100644 --- a/internal/catalog/internal/controllers/nodehealth/controller_test.go +++ b/internal/catalog/internal/controllers/nodehealth/controller_test.go @@ -73,7 +73,7 @@ type nodeHealthControllerTestSuite struct { } func (suite *nodeHealthControllerTestSuite) SetupTest() { - suite.resourceClient = svctest.RunResourceService(suite.T(), types.Register) + suite.resourceClient = svctest.RunResourceService(suite.T(), types.Register, types.RegisterDNSPolicy) suite.runtime = controller.Runtime{Client: suite.resourceClient, Logger: testutil.Logger(suite.T())} // The rest of the setup will be to prime the resource service with some data diff --git a/internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go b/internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go new file mode 100644 index 000000000000..17796a85c59a --- /dev/null +++ b/internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go @@ -0,0 +1,198 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package testhelpers + +import ( + "testing" + + "google.golang.org/protobuf/proto" + + "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/internal/resource/resourcetest" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" +) + +// WorkloadSelecting denotes a resource type that uses workload selectors. +type WorkloadSelecting interface { + proto.Message + GetWorkloads() *pbcatalog.WorkloadSelector +} + +func RunWorkloadSelectingTypeACLsTests[T WorkloadSelecting](t *testing.T, typ *pbresource.Type, + getData func(selector *pbcatalog.WorkloadSelector) T, + registerFunc func(registry resource.Registry), +) { + // Wire up a registry to generically invoke hooks + registry := resource.NewRegistry() + registerFunc(registry) + + cases := map[string]resourcetest.ACLTestCase{ + "no rules": { + Rules: ``, + Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), + Typ: typ, + ReadOK: resourcetest.DENY, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test read": { + Rules: `service "test" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write with named selectors and insufficient policy": { + Rules: `service "test" { policy = "write" }`, + Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write with prefixed selectors and insufficient policy": { + Rules: `service "test" { policy = "write" }`, + Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write with named selectors": { + Rules: `service "test" { policy = "write" } service "workload" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "service test write with multiple named selectors": { + Rules: `service "test" { policy = "write" } service "workload1" { policy = "read" } service "workload2" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload1", "workload2"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "service test write with multiple named selectors and insufficient policy": { + Rules: `service "test" { policy = "write" } service "workload1" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload1", "workload2"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write with multiple named selectors and prefixed policy": { + Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload1", "workload2"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "service test write with prefixed selectors": { + Rules: `service "test" { policy = "write" } service_prefix "workload-" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "service test write with prefixed selectors and a policy with more specific prefix than the selector": { + Rules: `service "test" { policy = "write" } service_prefix "workload-" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"wor"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + + "service test write with prefixed selectors and a policy with less specific prefix than the selector": { + Rules: `service "test" { policy = "write" } service_prefix "wor" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + // Prefix-based selectors should not allow writes when a policy only allows + // to read a specific service from that selector. + "service test write with prefixed selectors and a policy with a specific service": { + Rules: `service "test" { policy = "write" } service "workload" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write with multiple prefixed selectors": { + Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-1", "workload-2"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "service test write with multiple prefixed selectors and insufficient policy": { + Rules: `service "test" { policy = "write" } service_prefix "workload-1" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-1", "workload-2"}}), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write with a mix of named and prefixed selectors and insufficient policy": { + Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{ + Prefixes: []string{"workload-1", "workload-2"}, + Names: []string{"other-1", "other-2"}, + }), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write with a mix of named and prefixed selectors and prefixed policy": { + Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" } service_prefix "other" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{ + Prefixes: []string{"workload-1", "workload-2"}, + Names: []string{"other-1", "other-2"}, + }), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "service test write with a mix of named and prefixed selectors and both prefixed and specific policy": { + Rules: `service "test" { policy = "write" } service_prefix "workload" { policy = "read" } service "other-1" { policy = "read" } service "other-2" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{ + Prefixes: []string{"workload-1", "workload-2"}, + Names: []string{"other-1", "other-2"}, + }), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "service test write with a mix of named and prefixed selectors and wildcard service read policy": { + Rules: `service "test" { policy = "write" } service_prefix "" { policy = "read" }`, + Data: getData(&pbcatalog.WorkloadSelector{ + Prefixes: []string{"workload-1", "workload-2"}, + Names: []string{"other-1", "other-2"}, + }), + Typ: typ, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + resourcetest.RunACLTestCase(t, tc, registry) + }) + } +} diff --git a/internal/catalog/internal/types/acl_hooks.go b/internal/catalog/internal/types/acl_hooks.go new file mode 100644 index 000000000000..8250767f7254 --- /dev/null +++ b/internal/catalog/internal/types/acl_hooks.go @@ -0,0 +1,56 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package types + +import ( + "github.com/hashicorp/consul/acl" + "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/proto-public/pbresource" +) + +func aclReadHookResourceWithWorkloadSelector(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { + return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), authzContext) +} + +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(res.GetId().GetName(), authzContext) + if err != nil { + return err + } + + // Then also check whether we're allowed to select a service. + for _, name := range decodedService.GetData().GetWorkloads().GetNames() { + err = authorizer.ToAllowAuthorizer().ServiceReadAllowed(name, authzContext) + if err != nil { + return err + } + } + + for _, prefix := range decodedService.GetData().GetWorkloads().GetPrefixes() { + err = authorizer.ToAllowAuthorizer().ServiceReadPrefixAllowed(prefix, authzContext) + if err != nil { + return err + } + } + + return nil +} + +func ACLHooksForWorkloadSelectingType[T WorkloadSelecting]() *resource.ACLHooks { + return &resource.ACLHooks{ + Read: aclReadHookResourceWithWorkloadSelector, + 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 809dd6f880c2..8e9dd864a957 100644 --- a/internal/catalog/internal/types/dns_policy.go +++ b/internal/catalog/internal/types/dns_policy.go @@ -19,6 +19,7 @@ func RegisterDNSPolicy(r resource.Registry) { Proto: &pbcatalog.DNSPolicy{}, Scope: resource.ScopeNamespace, Validate: ValidateDNSPolicy, + ACLs: ACLHooksForWorkloadSelectingType[*pbcatalog.DNSPolicy](), }) } diff --git a/internal/catalog/internal/types/dns_policy_test.go b/internal/catalog/internal/types/dns_policy_test.go index 3a611171070a..1303d2878cf7 100644 --- a/internal/catalog/internal/types/dns_policy_test.go +++ b/internal/catalog/internal/types/dns_policy_test.go @@ -11,6 +11,7 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" + "github.com/hashicorp/consul/internal/catalog/internal/testhelpers" "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" @@ -161,3 +162,19 @@ func TestValidateDNSPolicy_EmptySelector(t *testing.T) { require.ErrorAs(t, err, &actual) require.Equal(t, expected, actual) } + +func TestDNSPolicyACLs(t *testing.T) { + // Wire up a registry to generically invoke hooks + registry := resource.NewRegistry() + RegisterDNSPolicy(registry) + + testhelpers.RunWorkloadSelectingTypeACLsTests[*pbcatalog.DNSPolicy](t, pbcatalog.DNSPolicyType, + func(selector *pbcatalog.WorkloadSelector) *pbcatalog.DNSPolicy { + return &pbcatalog.DNSPolicy{ + Workloads: selector, + Weights: &pbcatalog.Weights{Passing: 1, Warning: 0}, + } + }, + RegisterDNSPolicy, + ) +} diff --git a/internal/catalog/internal/types/failover_policy.go b/internal/catalog/internal/types/failover_policy.go index 4dc8b1bd8eb0..047bb9a95b05 100644 --- a/internal/catalog/internal/types/failover_policy.go +++ b/internal/catalog/internal/types/failover_policy.go @@ -25,7 +25,7 @@ func RegisterFailoverPolicy(r resource.Registry) { ACLs: &resource.ACLHooks{ Read: aclReadHookFailoverPolicy, Write: aclWriteHookFailoverPolicy, - List: aclListHookFailoverPolicy, + List: resource.NoOpACLListHook, }, }) } @@ -145,7 +145,7 @@ func ValidateFailoverPolicy(res *pbresource.Resource) error { Wrapped: err, } } - if portNameErr := validatePortName(portName); portNameErr != nil { + if portNameErr := ValidatePortName(portName); portNameErr != nil { merr = multierror.Append(merr, resource.ErrInvalidMapKey{ Map: "port_configs", Key: portName, @@ -245,7 +245,7 @@ func validateFailoverPolicyDestination(dest *pbcatalog.FailoverDestination, port // assumed and will be reconciled. if dest.Port != "" { if ported { - if portNameErr := validatePortName(dest.Port); portNameErr != nil { + if portNameErr := ValidatePortName(dest.Port); portNameErr != nil { merr = multierror.Append(merr, wrapErr(resource.ErrInvalidField{ Name: "port", Wrapped: portNameErr, @@ -371,9 +371,3 @@ func aclWriteHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.Aut return nil } - -func aclListHookFailoverPolicy(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext) error { - // No-op List permission as we want to default to filtering resources - // from the list using the Read enforcement. - return nil -} diff --git a/internal/catalog/internal/types/failover_policy_test.go b/internal/catalog/internal/types/failover_policy_test.go index 8abe5d5cb74d..5628ed57741c 100644 --- a/internal/catalog/internal/types/failover_policy_test.go +++ b/internal/catalog/internal/types/failover_policy_test.go @@ -4,7 +4,7 @@ package types import ( - "strings" + "fmt" "testing" "github.com/stretchr/testify/require" @@ -140,7 +140,7 @@ func TestMutateFailoverPolicy(t *testing.T) { }, }, "dest ref tenancy defaulting": { - policyTenancy: newTestTenancy("foo.bar"), + policyTenancy: resourcetest.Tenancy("foo.bar"), failover: &pbcatalog.FailoverPolicy{ Config: &pbcatalog.FailoverConfig{ Mode: pbcatalog.FailoverMode_FAILOVER_MODE_SEQUENTIAL, @@ -685,105 +685,147 @@ func TestFailoverPolicyACLs(t *testing.T) { registry := resource.NewRegistry() Register(registry) + newFailover := func(t *testing.T, name, tenancyStr string, destRefs []*pbresource.Reference) []*pbresource.Resource { + var dr []*pbcatalog.FailoverDestination + for _, destRef := range destRefs { + dr = append(dr, &pbcatalog.FailoverDestination{Ref: destRef}) + } + + res1 := resourcetest.Resource(pbcatalog.FailoverPolicyType, name). + WithTenancy(resourcetest.Tenancy(tenancyStr)). + WithData(t, &pbcatalog.FailoverPolicy{ + Config: &pbcatalog.FailoverConfig{Destinations: dr}, + }). + Build() + resourcetest.ValidateAndNormalize(t, registry, res1) + + res2 := resourcetest.Resource(pbcatalog.FailoverPolicyType, name). + WithTenancy(resourcetest.Tenancy(tenancyStr)). + WithData(t, &pbcatalog.FailoverPolicy{ + PortConfigs: map[string]*pbcatalog.FailoverConfig{ + "http": {Destinations: dr}, + }, + }). + Build() + resourcetest.ValidateAndNormalize(t, registry, res2) + + return []*pbresource.Resource{res1, res2} + } + type testcase struct { + res *pbresource.Resource rules string check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource) readOK string writeOK string - listOK string } const ( - DENY = "deny" - ALLOW = "allow" - DEFAULT = "default" + DENY = resourcetest.DENY + ALLOW = resourcetest.ALLOW + DEFAULT = resourcetest.DEFAULT ) - checkF := func(t *testing.T, expect string, got error) { - switch expect { - case ALLOW: - if acl.IsErrPermissionDenied(got) { - t.Fatal("should be allowed") - } - case DENY: - if !acl.IsErrPermissionDenied(got) { - t.Fatal("should be denied") - } - case DEFAULT: - require.Nil(t, got, "expected fallthrough decision") - default: - t.Fatalf("unexpected expectation: %q", expect) - } + serviceRef := func(tenancy, name string) *pbresource.Reference { + return newRefWithTenancy(pbcatalog.ServiceType, tenancy, name) } - reg, ok := registry.Resolve(pbcatalog.FailoverPolicyType) - require.True(t, ok) + resOneDest := func(tenancy, destTenancy string) []*pbresource.Resource { + return newFailover(t, "api", tenancy, []*pbresource.Reference{ + serviceRef(destTenancy, "dest1"), + }) + } - run := func(t *testing.T, tc testcase) { - failoverData := &pbcatalog.FailoverPolicy{ - Config: &pbcatalog.FailoverConfig{ - Destinations: []*pbcatalog.FailoverDestination{ - {Ref: newRef(pbcatalog.ServiceType, "api-backup")}, - }, - }, - } - res := resourcetest.Resource(pbcatalog.FailoverPolicyType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, failoverData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) + resTwoDests := func(tenancy, destTenancy string) []*pbresource.Resource { + return newFailover(t, "api", tenancy, []*pbresource.Reference{ + serviceRef(destTenancy, "dest1"), + serviceRef(destTenancy, "dest2"), + }) + } - config := acl.Config{ - WildcardName: structs.WildcardSpecifier, + run := func(t *testing.T, name string, tc resourcetest.ACLTestCase) { + t.Run(name, func(t *testing.T) { + resourcetest.RunACLTestCase(t, tc, registry) + }) + } + + isEnterprise := (structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default") + + serviceRead := func(partition, namespace, name string) string { + if isEnterprise { + return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "read" } } }`, partition, namespace, name) + } + return fmt.Sprintf(` service %q { policy = "read" } `, name) + } + serviceWrite := func(partition, namespace, name string) string { + if isEnterprise { + return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "write" } } }`, partition, namespace, name) } - authz, err := acl.NewAuthorizerFromRules(tc.rules, &config, nil) - require.NoError(t, err) - authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) + return fmt.Sprintf(` service %q { policy = "write" } `, name) + } - t.Run("read", func(t *testing.T) { - err := reg.ACLs.Read(authz, &acl.AuthorizerContext{}, res.Id, nil) - checkF(t, tc.readOK, err) - }) - t.Run("write", func(t *testing.T) { - err := reg.ACLs.Write(authz, &acl.AuthorizerContext{}, res) - checkF(t, tc.writeOK, err) - }) - t.Run("list", func(t *testing.T) { - err := reg.ACLs.List(authz, &acl.AuthorizerContext{}) - checkF(t, tc.listOK, err) - }) + assert := func(t *testing.T, name string, rules string, resList []*pbresource.Resource, readOK, writeOK string) { + for i, res := range resList { + tc := resourcetest.ACLTestCase{ + AuthCtx: resource.AuthorizerContext(res.Id.Tenancy), + Res: res, + Rules: rules, + ReadOK: readOK, + WriteOK: writeOK, + ListOK: DEFAULT, + } + run(t, fmt.Sprintf("%s-%d", name, i), tc) + } } - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "service api read": { - rules: `service "api" { policy = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "service api write": { - rules: `service "api" { policy = "write" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "service api write and api-backup read": { - rules: `service "api" { policy = "write" } service "api-backup" { policy = "read" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, + tenancies := []string{"default.default"} + if isEnterprise { + tenancies = append(tenancies, "default.foo", "alpha.default", "alpha.foo") } - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) + for _, policyTenancyStr := range tenancies { + t.Run("policy tenancy: "+policyTenancyStr, func(t *testing.T) { + for _, destTenancyStr := range tenancies { + t.Run("dest tenancy: "+destTenancyStr, func(t *testing.T) { + for _, aclTenancyStr := range tenancies { + t.Run("acl tenancy: "+aclTenancyStr, func(t *testing.T) { + aclTenancy := resourcetest.Tenancy(aclTenancyStr) + + maybe := func(match string, parentOnly bool) string { + if policyTenancyStr != aclTenancyStr { + return DENY + } + if !parentOnly && destTenancyStr != aclTenancyStr { + return DENY + } + return match + } + + t.Run("no rules", func(t *testing.T) { + rules := `` + assert(t, "1dest", rules, resOneDest(policyTenancyStr, destTenancyStr), DENY, DENY) + assert(t, "2dests", rules, resTwoDests(policyTenancyStr, destTenancyStr), DENY, DENY) + }) + t.Run("api:read", func(t *testing.T) { + rules := serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "api") + assert(t, "1dest", rules, resOneDest(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) + assert(t, "2dests", rules, resTwoDests(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) + }) + t.Run("api:write", func(t *testing.T) { + rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api") + assert(t, "1dest", rules, resOneDest(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) + assert(t, "2dests", rules, resTwoDests(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) + }) + t.Run("api:write dest1:read", func(t *testing.T) { + rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api") + + serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "dest1") + assert(t, "1dest", rules, resOneDest(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), maybe(ALLOW, false)) + assert(t, "2dests", rules, resTwoDests(policyTenancyStr, destTenancyStr), maybe(ALLOW, true), DENY) + }) + }) + } + }) + } }) } } @@ -796,7 +838,7 @@ func newRef(typ *pbresource.Type, name string) *pbresource.Reference { func newRefWithTenancy(typ *pbresource.Type, tenancyStr, name string) *pbresource.Reference { return resourcetest.Resource(typ, name). - WithTenancy(newTestTenancy(tenancyStr)). + WithTenancy(resourcetest.Tenancy(tenancyStr)). Reference("") } @@ -805,22 +847,3 @@ func newRefWithPeer(typ *pbresource.Type, name string, peer string) *pbresource. ref.Tenancy.PeerName = peer return ref } - -func newTestTenancy(s string) *pbresource.Tenancy { - parts := strings.Split(s, ".") - switch len(parts) { - case 0: - return resource.DefaultClusteredTenancy() - case 1: - v := resource.DefaultPartitionedTenancy() - v.Partition = parts[0] - return v - case 2: - v := resource.DefaultNamespacedTenancy() - v.Partition = parts[0] - v.Namespace = parts[1] - return v - default: - return &pbresource.Tenancy{Partition: "BAD", Namespace: "BAD", PeerName: "BAD"} - } -} diff --git a/internal/catalog/internal/types/health_checks.go b/internal/catalog/internal/types/health_checks.go index b470be331feb..1333e2368d88 100644 --- a/internal/catalog/internal/types/health_checks.go +++ b/internal/catalog/internal/types/health_checks.go @@ -17,6 +17,7 @@ func RegisterHealthChecks(r resource.Registry) { Proto: &pbcatalog.HealthChecks{}, Scope: resource.ScopeNamespace, Validate: ValidateHealthChecks, + ACLs: ACLHooksForWorkloadSelectingType[*pbcatalog.HealthChecks](), }) } diff --git a/internal/catalog/internal/types/health_checks_test.go b/internal/catalog/internal/types/health_checks_test.go index 8af0ffde9fac..c9cdf01ae84c 100644 --- a/internal/catalog/internal/types/health_checks_test.go +++ b/internal/catalog/internal/types/health_checks_test.go @@ -12,6 +12,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/durationpb" + "github.com/hashicorp/consul/internal/catalog/internal/testhelpers" "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" @@ -196,3 +197,12 @@ func TestValidateHealthChecks_EmptySelector(t *testing.T) { require.ErrorAs(t, err, &actual) require.Equal(t, expected, actual) } + +func TestHealthChecksACLs(t *testing.T) { + testhelpers.RunWorkloadSelectingTypeACLsTests[*pbcatalog.HealthChecks](t, pbcatalog.HealthChecksType, + func(selector *pbcatalog.WorkloadSelector) *pbcatalog.HealthChecks { + return &pbcatalog.HealthChecks{Workloads: selector} + }, + RegisterHealthChecks, + ) +} diff --git a/internal/catalog/internal/types/health_status.go b/internal/catalog/internal/types/health_status.go index 99b153895c1f..fe92e858b025 100644 --- a/internal/catalog/internal/types/health_status.go +++ b/internal/catalog/internal/types/health_status.go @@ -6,6 +6,7 @@ package types import ( "github.com/hashicorp/go-multierror" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" @@ -17,6 +18,11 @@ func RegisterHealthStatus(r resource.Registry) { Proto: &pbcatalog.HealthStatus{}, Scope: resource.ScopeNamespace, Validate: ValidateHealthStatus, + ACLs: &resource.ACLHooks{ + Read: aclReadHookHealthStatus, + Write: aclWriteHookHealthStatus, + List: resource.NoOpACLListHook, + }, }) } @@ -66,3 +72,32 @@ func ValidateHealthStatus(res *pbresource.Resource) error { return err } + +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) + } + + if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.NodeType) { + return authorizer.ToAllowAuthorizer().NodeReadAllowed(res.GetOwner().GetName(), authzContext) + } + + return acl.PermissionDenied("cannot read catalog.HealthStatus because there is no owner") +} + +func aclWriteHookHealthStatus(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { + // For a health status of a workload we need to check service:write perms. + if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.WorkloadType) { + return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(res.GetOwner().GetName(), authzContext) + } + + if res.GetOwner() != nil && resource.EqualType(res.GetOwner().GetType(), pbcatalog.NodeType) { + return authorizer.ToAllowAuthorizer().NodeWriteAllowed(res.GetOwner().GetName(), authzContext) + } + + return acl.PermissionDenied("cannot write catalog.HealthStatus because there is no owner") +} diff --git a/internal/catalog/internal/types/health_status_test.go b/internal/catalog/internal/types/health_status_test.go index 654573d24a53..9482e4770e40 100644 --- a/internal/catalog/internal/types/health_status_test.go +++ b/internal/catalog/internal/types/health_status_test.go @@ -11,6 +11,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/internal/resource/resourcetest" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -214,3 +215,106 @@ func TestValidateHealthStatus_InvalidOwner(t *testing.T) { }) } } + +func TestHealthStatusACLs(t *testing.T) { + registry := resource.NewRegistry() + Register(registry) + + workload := resourcetest.Resource(pbcatalog.WorkloadType, "test").ID() + node := resourcetest.Resource(pbcatalog.NodeType, "test").ID() + + healthStatusData := &pbcatalog.HealthStatus{ + Type: "tcp", + Status: pbcatalog.Health_HEALTH_PASSING, + } + + cases := map[string]resourcetest.ACLTestCase{ + "no rules": { + Rules: ``, + Data: healthStatusData, + Owner: workload, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.DENY, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test read": { + Rules: `service "test" { policy = "read" }`, + Data: healthStatusData, + Owner: workload, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write": { + Rules: `service "test" { policy = "write" }`, + Data: healthStatusData, + Owner: workload, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "service test read with node owner": { + Rules: `service "test" { policy = "read" }`, + Data: healthStatusData, + Owner: node, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.DENY, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "service test write with node owner": { + Rules: `service "test" { policy = "write" }`, + Data: healthStatusData, + Owner: node, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.DENY, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "node test read with node owner": { + Rules: `node "test" { policy = "read" }`, + Data: healthStatusData, + Owner: node, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "node test write with node owner": { + Rules: `node "test" { policy = "write" }`, + Data: healthStatusData, + Owner: node, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + "node test read with workload owner": { + Rules: `node "test" { policy = "read" }`, + Data: healthStatusData, + Owner: workload, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.DENY, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "node test write with workload owner": { + Rules: `node "test" { policy = "write" }`, + Data: healthStatusData, + Owner: workload, + Typ: pbcatalog.HealthStatusType, + ReadOK: resourcetest.DENY, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + resourcetest.RunACLTestCase(t, tc, registry) + }) + } +} diff --git a/internal/catalog/internal/types/node.go b/internal/catalog/internal/types/node.go index 9c59228a49b6..42ac833c6e7d 100644 --- a/internal/catalog/internal/types/node.go +++ b/internal/catalog/internal/types/node.go @@ -6,6 +6,7 @@ package types import ( "github.com/hashicorp/go-multierror" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" @@ -22,6 +23,11 @@ func RegisterNode(r resource.Registry) { // Until that time, Node will remain namespace scoped. Scope: resource.ScopeNamespace, Validate: ValidateNode, + ACLs: &resource.ACLHooks{ + Read: aclReadHookNode, + Write: aclWriteHookNode, + List: resource.NoOpACLListHook, + }, }) } @@ -80,3 +86,11 @@ func validateNodeAddress(addr *pbcatalog.NodeAddress) error { return nil } + +func aclReadHookNode(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { + return authorizer.ToAllowAuthorizer().NodeReadAllowed(id.GetName(), authzContext) +} + +func aclWriteHookNode(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { + return authorizer.ToAllowAuthorizer().NodeWriteAllowed(res.GetId().GetName(), authzContext) +} diff --git a/internal/catalog/internal/types/node_test.go b/internal/catalog/internal/types/node_test.go index 130551fad2b6..5a678745e3a3 100644 --- a/internal/catalog/internal/types/node_test.go +++ b/internal/catalog/internal/types/node_test.go @@ -11,6 +11,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/internal/resource/resourcetest" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -127,3 +128,48 @@ func TestValidateNode_AddressMissingHost(t *testing.T) { require.ErrorAs(t, err, &actual) require.Equal(t, expected, actual) } + +func TestNodeACLs(t *testing.T) { + registry := resource.NewRegistry() + Register(registry) + + nodeData := &pbcatalog.Node{ + Addresses: []*pbcatalog.NodeAddress{ + { + Host: "1.1.1.1", + }, + }, + } + cases := map[string]resourcetest.ACLTestCase{ + "no rules": { + Rules: ``, + Data: nodeData, + Typ: pbcatalog.NodeType, + ReadOK: resourcetest.DENY, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "node test read": { + Rules: `node "test" { policy = "read" }`, + Data: nodeData, + Typ: pbcatalog.NodeType, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.DENY, + ListOK: resourcetest.DEFAULT, + }, + "node test write": { + Rules: `node "test" { policy = "write" }`, + Data: nodeData, + Typ: pbcatalog.NodeType, + ReadOK: resourcetest.ALLOW, + WriteOK: resourcetest.ALLOW, + ListOK: resourcetest.DEFAULT, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + resourcetest.RunACLTestCase(t, tc, registry) + }) + } +} diff --git a/internal/catalog/internal/types/service.go b/internal/catalog/internal/types/service.go index 4cefb362e78f..a91f3a7c5180 100644 --- a/internal/catalog/internal/types/service.go +++ b/internal/catalog/internal/types/service.go @@ -20,6 +20,7 @@ func RegisterService(r resource.Registry) { Scope: resource.ScopeNamespace, Validate: ValidateService, Mutate: MutateService, + ACLs: ACLHooksForWorkloadSelectingType[*pbcatalog.Service](), }) } @@ -89,7 +90,7 @@ func ValidateService(res *pbresource.Resource) error { } // validate the target port - if nameErr := validatePortName(port.TargetPort); nameErr != nil { + if nameErr := ValidatePortName(port.TargetPort); nameErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "ports", Index: idx, @@ -100,7 +101,7 @@ func ValidateService(res *pbresource.Resource) error { }) } - if protoErr := validateProtocol(port.Protocol); protoErr != nil { + if protoErr := ValidateProtocol(port.Protocol); protoErr != nil { err = multierror.Append(err, resource.ErrInvalidListElement{ Name: "ports", Index: idx, diff --git a/internal/catalog/internal/types/service_endpoints.go b/internal/catalog/internal/types/service_endpoints.go index 8008ada845b4..1991c455ad90 100644 --- a/internal/catalog/internal/types/service_endpoints.go +++ b/internal/catalog/internal/types/service_endpoints.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/go-multierror" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" @@ -20,6 +21,15 @@ func RegisterServiceEndpoints(r resource.Registry) { Scope: resource.ScopeNamespace, Validate: ValidateServiceEndpoints, Mutate: MutateServiceEndpoints, + ACLs: &resource.ACLHooks{ + Read: func(authorizer acl.Authorizer, context *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { + return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), context) + }, + Write: func(authorizer acl.Authorizer, context *acl.AuthorizerContext, p *pbresource.Resource) error { + return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(p.GetId().GetName(), context) + }, + List: resource.NoOpACLListHook, + }, }) } @@ -126,7 +136,7 @@ func validateEndpoint(endpoint *pbcatalog.Endpoint, res *pbresource.Resource) er // Validate the endpoints ports for portName, port := range endpoint.Ports { // Port names must be DNS labels - if portNameErr := validatePortName(portName); portNameErr != nil { + if portNameErr := ValidatePortName(portName); portNameErr != nil { err = multierror.Append(err, resource.ErrInvalidMapKey{ Map: "ports", Key: portName, @@ -134,7 +144,7 @@ func validateEndpoint(endpoint *pbcatalog.Endpoint, res *pbresource.Resource) er }) } - if protoErr := validateProtocol(port.Protocol); protoErr != nil { + if protoErr := ValidateProtocol(port.Protocol); protoErr != nil { err = multierror.Append(err, resource.ErrInvalidMapValue{ Map: "ports", Key: portName, diff --git a/internal/catalog/internal/types/service_endpoints_test.go b/internal/catalog/internal/types/service_endpoints_test.go index d210ba1aaafd..7a298e397949 100644 --- a/internal/catalog/internal/types/service_endpoints_test.go +++ b/internal/catalog/internal/types/service_endpoints_test.go @@ -258,3 +258,47 @@ func TestMutateServiceEndpoints_PopulateOwner(t *testing.T) { require.True(t, resource.EqualTenancy(res.Owner.Tenancy, defaultEndpointTenancy)) require.Equal(t, res.Owner.Name, res.Id.Name) } + +func TestServiceEndpointsACLs(t *testing.T) { + registry := resource.NewRegistry() + Register(registry) + + service := rtest.Resource(pbcatalog.ServiceType, "test"). + WithTenancy(resource.DefaultNamespacedTenancy()).ID() + serviceEndpointsData := &pbcatalog.ServiceEndpoints{} + cases := map[string]rtest.ACLTestCase{ + "no rules": { + Rules: ``, + Data: serviceEndpointsData, + Owner: service, + Typ: pbcatalog.ServiceEndpointsType, + ReadOK: rtest.DENY, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test read": { + Rules: `service "test" { policy = "read" }`, + Data: serviceEndpointsData, + Owner: service, + Typ: pbcatalog.ServiceEndpointsType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test write": { + Rules: `service "test" { policy = "write" }`, + Data: serviceEndpointsData, + Owner: service, + Typ: pbcatalog.ServiceEndpointsType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.ALLOW, + ListOK: rtest.DEFAULT, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + rtest.RunACLTestCase(t, tc, registry) + }) + } +} diff --git a/internal/catalog/internal/types/service_test.go b/internal/catalog/internal/types/service_test.go index b47c02218405..18649dda9a0a 100644 --- a/internal/catalog/internal/types/service_test.go +++ b/internal/catalog/internal/types/service_test.go @@ -10,6 +10,7 @@ import ( "google.golang.org/protobuf/reflect/protoreflect" "google.golang.org/protobuf/types/known/anypb" + "github.com/hashicorp/consul/internal/catalog/internal/testhelpers" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/resourcetest" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" @@ -275,3 +276,12 @@ func TestValidateService_InvalidVIP(t *testing.T) { require.Error(t, err) require.ErrorIs(t, err, errNotIPAddress) } + +func TestServiceACLs(t *testing.T) { + testhelpers.RunWorkloadSelectingTypeACLsTests[*pbcatalog.Service](t, pbcatalog.ServiceType, + func(selector *pbcatalog.WorkloadSelector) *pbcatalog.Service { + return &pbcatalog.Service{Workloads: selector} + }, + RegisterService, + ) +} diff --git a/internal/catalog/internal/types/types.go b/internal/catalog/internal/types/types.go index 6ce29a265963..15ed6b148de7 100644 --- a/internal/catalog/internal/types/types.go +++ b/internal/catalog/internal/types/types.go @@ -13,8 +13,10 @@ func Register(r resource.Registry) { RegisterServiceEndpoints(r) RegisterNode(r) RegisterHealthStatus(r) - RegisterHealthChecks(r) - RegisterDNSPolicy(r) - RegisterVirtualIPs(r) RegisterFailoverPolicy(r) + + // todo (v2): re-register once these resources are implemented. + //RegisterHealthChecks(r) + //RegisterDNSPolicy(r) + //RegisterVirtualIPs(r) } diff --git a/internal/catalog/internal/types/types_test.go b/internal/catalog/internal/types/types_test.go index ba4243b62805..4facd921c368 100644 --- a/internal/catalog/internal/types/types_test.go +++ b/internal/catalog/internal/types/types_test.go @@ -24,9 +24,9 @@ func TestTypeRegistration(t *testing.T) { pbcatalog.ServiceEndpointsKind, pbcatalog.NodeKind, pbcatalog.HealthStatusKind, - pbcatalog.HealthChecksKind, - pbcatalog.DNSPolicyKind, // todo (ishustava): uncomment once we implement these + //pbcatalog.HealthChecksKind, + //pbcatalog.DNSPolicyKind, //pbcatalog.VirtualIPsKind, } diff --git a/internal/catalog/internal/types/validators.go b/internal/catalog/internal/types/validators.go index 542bb705b5aa..07dfbd356967 100644 --- a/internal/catalog/internal/types/validators.go +++ b/internal/catalog/internal/types/validators.go @@ -56,7 +56,7 @@ func isValidDNSLabel(label string) bool { return dnsLabelMatcher.Match([]byte(label)) } -func isValidUnixSocketPath(host string) bool { +func IsValidUnixSocketPath(host string) bool { if len(host) > maxUnixSocketPathLen || !strings.HasPrefix(host, "unix://") || strings.Contains(host, "\000") { return false } @@ -71,7 +71,7 @@ func validateWorkloadHost(host string) error { } // Check if the host represents an IP address, unix socket path or a DNS name - if !isValidIPAddress(host) && !isValidUnixSocketPath(host) && !isValidDNSName(host) { + if !isValidIPAddress(host) && !IsValidUnixSocketPath(host) && !isValidDNSName(host) { return errInvalidWorkloadHostFormat{Host: host} } @@ -139,7 +139,7 @@ func validateIPAddress(ip string) error { return nil } -func validatePortName(name string) error { +func ValidatePortName(name string) error { if name == "" { return resource.ErrEmpty } @@ -151,7 +151,8 @@ func validatePortName(name string) error { return nil } -func validateProtocol(protocol pbcatalog.Protocol) error { +func ValidateProtocol(protocol pbcatalog.Protocol) error { + // enumcover:pbcatalog.Protocol switch protocol { case pbcatalog.Protocol_PROTOCOL_UNSPECIFIED, // means pbcatalog.FailoverMode_FAILOVER_MODE_TCP @@ -184,7 +185,7 @@ func validateWorkloadAddress(addr *pbcatalog.WorkloadAddress, ports map[string]* // Ensure that unix sockets reference exactly 1 port. They may also indirectly reference 1 port // by the workload having only a single port and omitting any explicit port assignment. - if isValidUnixSocketPath(addr.Host) && + if IsValidUnixSocketPath(addr.Host) && (len(addr.Ports) > 1 || (len(addr.Ports) == 0 && len(ports) > 1)) { err = multierror.Append(err, errUnixSocketMultiport) } @@ -240,6 +241,7 @@ func validateReference(allowedType *pbresource.Type, allowedTenancy *pbresource. } func validateHealth(health pbcatalog.Health) error { + // enumcover:pbcatalog.Health switch health { case pbcatalog.Health_HEALTH_ANY, pbcatalog.Health_HEALTH_PASSING, diff --git a/internal/catalog/internal/types/validators_test.go b/internal/catalog/internal/types/validators_test.go index a8a8f740394d..7a334727a998 100644 --- a/internal/catalog/internal/types/validators_test.go +++ b/internal/catalog/internal/types/validators_test.go @@ -178,7 +178,7 @@ func TestIsValidUnixSocketPath(t *testing.T) { for name, tcase := range cases { t.Run(name, func(t *testing.T) { - require.Equal(t, tcase.valid, isValidUnixSocketPath(tcase.name)) + require.Equal(t, tcase.valid, IsValidUnixSocketPath(tcase.name)) }) } } @@ -361,38 +361,18 @@ func TestValidatePortName(t *testing.T) { // test for the isValidDNSLabel function. t.Run("empty", func(t *testing.T) { - require.Equal(t, resource.ErrEmpty, validatePortName("")) + require.Equal(t, resource.ErrEmpty, ValidatePortName("")) }) t.Run("invalid", func(t *testing.T) { - require.Equal(t, errNotDNSLabel, validatePortName("foo.com")) + require.Equal(t, errNotDNSLabel, ValidatePortName("foo.com")) }) t.Run("ok", func(t *testing.T) { - require.NoError(t, validatePortName("http")) + require.NoError(t, ValidatePortName("http")) }) } -func TestValidateProtocol(t *testing.T) { - // this test simply verifies that we accept all enum values specified in our proto - // in order to avoid validator drift. - for name, value := range pbcatalog.Protocol_value { - t.Run(name, func(t *testing.T) { - require.NoError(t, validateProtocol(pbcatalog.Protocol(value))) - }) - } -} - -func TestValidateHealth(t *testing.T) { - // this test simply verifies that we accept all enum values specified in our proto - // in order to avoid validator drift. - for name, value := range pbcatalog.Health_value { - t.Run(name, func(t *testing.T) { - require.NoError(t, validateHealth(pbcatalog.Health(value))) - }) - } -} - func TestValidateWorkloadAddress(t *testing.T) { type testCase struct { addr *pbcatalog.WorkloadAddress diff --git a/internal/catalog/internal/types/virtual_ips.go b/internal/catalog/internal/types/virtual_ips.go index 7a4cee276ae6..9c7a06547405 100644 --- a/internal/catalog/internal/types/virtual_ips.go +++ b/internal/catalog/internal/types/virtual_ips.go @@ -6,19 +6,28 @@ package types import ( "github.com/hashicorp/go-multierror" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" ) func RegisterVirtualIPs(r resource.Registry) { - // todo (ishustava): uncomment when we implement it - //r.Register(resource.Registration{ - // Type: pbcatalog.VirtualIPsV2Beta1Type, - // Proto: &pbcatalog.VirtualIPs{}, - // Scope: resource.ScopeNamespace, - // Validate: ValidateVirtualIPs, - //}) + r.Register(resource.Registration{ + Type: pbcatalog.VirtualIPsType, + Proto: &pbcatalog.VirtualIPs{}, + Scope: resource.ScopeNamespace, + Validate: ValidateVirtualIPs, + ACLs: &resource.ACLHooks{ + Read: func(authorizer acl.Authorizer, context *acl.AuthorizerContext, id *pbresource.ID, p *pbresource.Resource) error { + return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), context) + }, + Write: func(authorizer acl.Authorizer, context *acl.AuthorizerContext, p *pbresource.Resource) error { + return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(p.GetId().GetName(), context) + }, + List: resource.NoOpACLListHook, + }, + }) } func ValidateVirtualIPs(res *pbresource.Resource) error { diff --git a/internal/catalog/internal/types/virtual_ips_test.go b/internal/catalog/internal/types/virtual_ips_test.go index c7ed70972530..0107e1cfd94f 100644 --- a/internal/catalog/internal/types/virtual_ips_test.go +++ b/internal/catalog/internal/types/virtual_ips_test.go @@ -11,6 +11,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/consul/internal/resource" + rtest "github.com/hashicorp/consul/internal/resource/resourcetest" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -81,3 +82,47 @@ func TestValidateVirtualIPs_InvalidIP(t *testing.T) { require.Error(t, err) require.ErrorIs(t, err, errNotIPAddress) } + +func TestVirtualIPsACLs(t *testing.T) { + registry := resource.NewRegistry() + RegisterVirtualIPs(registry) + + service := rtest.Resource(pbcatalog.ServiceType, "test"). + WithTenancy(resource.DefaultNamespacedTenancy()).ID() + virtualIPsData := &pbcatalog.VirtualIPs{} + cases := map[string]rtest.ACLTestCase{ + "no rules": { + Rules: ``, + Data: virtualIPsData, + Owner: service, + Typ: pbcatalog.VirtualIPsType, + ReadOK: rtest.DENY, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test read": { + Rules: `service "test" { policy = "read" }`, + Data: virtualIPsData, + Owner: service, + Typ: pbcatalog.VirtualIPsType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test write": { + Rules: `service "test" { policy = "write" }`, + Data: virtualIPsData, + Owner: service, + Typ: pbcatalog.VirtualIPsType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.ALLOW, + ListOK: rtest.DEFAULT, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + rtest.RunACLTestCase(t, tc, registry) + }) + } +} diff --git a/internal/catalog/internal/types/workload.go b/internal/catalog/internal/types/workload.go index 961a85346c4f..c09513a4a5b3 100644 --- a/internal/catalog/internal/types/workload.go +++ b/internal/catalog/internal/types/workload.go @@ -9,6 +9,7 @@ import ( "github.com/hashicorp/go-multierror" + "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/internal/resource" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" @@ -20,6 +21,11 @@ func RegisterWorkload(r resource.Registry) { Proto: &pbcatalog.Workload{}, Scope: resource.ScopeNamespace, Validate: ValidateWorkload, + ACLs: &resource.ACLHooks{ + Read: aclReadHookWorkload, + Write: aclWriteHookWorkload, + List: resource.NoOpACLListHook, + }, }) } @@ -44,7 +50,7 @@ func ValidateWorkload(res *pbresource.Resource) error { // Validate the Workload Ports for portName, port := range workload.Ports { - if portNameErr := validatePortName(portName); portNameErr != nil { + if portNameErr := ValidatePortName(portName); portNameErr != nil { err = multierror.Append(err, resource.ErrInvalidMapKey{ Map: "ports", Key: portName, @@ -64,7 +70,7 @@ func ValidateWorkload(res *pbresource.Resource) error { }) } - if protoErr := validateProtocol(port.Protocol); protoErr != nil { + if protoErr := ValidateProtocol(port.Protocol); protoErr != nil { err = multierror.Append(err, resource.ErrInvalidMapValue{ Map: "ports", Key: portName, @@ -145,3 +151,32 @@ func ValidateWorkload(res *pbresource.Resource) error { return err } + +func aclReadHookWorkload(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { + return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), authzContext) +} + +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) + if err != nil { + return err + } + + // Check node:read permissions if node is specified. + if decodedWorkload.GetData().GetNodeName() != "" { + return authorizer.ToAllowAuthorizer().NodeReadAllowed(decodedWorkload.GetData().GetNodeName(), authzContext) + } + + // Check identity:read permissions if identity is specified. + if decodedWorkload.GetData().GetIdentity() != "" { + return authorizer.ToAllowAuthorizer().IdentityReadAllowed(decodedWorkload.GetData().GetIdentity(), authzContext) + } + + return nil +} diff --git a/internal/catalog/internal/types/workload_selecting.go b/internal/catalog/internal/types/workload_selecting.go new file mode 100644 index 000000000000..6d129bfaa693 --- /dev/null +++ b/internal/catalog/internal/types/workload_selecting.go @@ -0,0 +1,16 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package types + +import ( + "google.golang.org/protobuf/proto" + + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" +) + +// WorkloadSelecting denotes a resource type that uses workload selectors. +type WorkloadSelecting interface { + proto.Message + GetWorkloads() *pbcatalog.WorkloadSelector +} diff --git a/internal/catalog/internal/types/workload_test.go b/internal/catalog/internal/types/workload_test.go index e55d9a44fd2b..1c7f7b825594 100644 --- a/internal/catalog/internal/types/workload_test.go +++ b/internal/catalog/internal/types/workload_test.go @@ -11,6 +11,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/consul/internal/resource" + rtest "github.com/hashicorp/consul/internal/resource/resourcetest" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" ) @@ -304,3 +305,160 @@ func TestValidateWorkload_Locality(t *testing.T) { require.ErrorAs(t, err, &actual) require.Equal(t, expected, actual) } + +func TestWorkloadACLs(t *testing.T) { + registry := resource.NewRegistry() + Register(registry) + + cases := map[string]rtest.ACLTestCase{ + "no rules": { + Rules: ``, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.DENY, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test read": { + Rules: `service "test" { policy = "read" }`, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test write": { + Rules: `service "test" { policy = "write" }`, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.ALLOW, + ListOK: rtest.DEFAULT, + }, + "service test write with node": { + Rules: `service "test" { policy = "write" }`, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + NodeName: "test-node", + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test write with workload identity": { + Rules: `service "test" { policy = "write" }`, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + Identity: "test-identity", + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test write with workload identity and node": { + Rules: `service "test" { policy = "write" }`, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + NodeName: "test-node", + Identity: "test-identity", + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.DENY, + ListOK: rtest.DEFAULT, + }, + "service test write with node and node policy": { + Rules: `service "test" { policy = "write" } node "test-node" { policy = "read" }`, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + NodeName: "test-node", + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.ALLOW, + ListOK: rtest.DEFAULT, + }, + "service test write with workload identity and identity policy ": { + Rules: `service "test" { policy = "write" } identity "test-identity" { policy = "read" }`, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + Identity: "test-identity", + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.ALLOW, + ListOK: rtest.DEFAULT, + }, + "service test write with workload identity and node with both node and identity policy": { + Rules: `service "test" { policy = "write" } identity "test-identity" { policy = "read" } node "test-node" { policy = "read" }`, + Data: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: "1.1.1.1"}, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "tcp": {Port: 8080}, + }, + NodeName: "test-node", + Identity: "test-identity", + }, + Typ: pbcatalog.WorkloadType, + ReadOK: rtest.ALLOW, + WriteOK: rtest.ALLOW, + ListOK: rtest.DEFAULT, + }, + } + + for name, tc := range cases { + t.Run(name, func(t *testing.T) { + rtest.RunACLTestCase(t, tc, registry) + }) + } +} diff --git a/internal/mesh/internal/controllers/proxyconfiguration/sort_test.go b/internal/mesh/internal/controllers/proxyconfiguration/sort_test.go index 36033a47e477..1fbf8254ee60 100644 --- a/internal/mesh/internal/controllers/proxyconfiguration/sort_test.go +++ b/internal/mesh/internal/controllers/proxyconfiguration/sort_test.go @@ -99,7 +99,8 @@ func TestSortProxyConfigurations(t *testing.T) { var decProxyCfgs []*types.DecodedProxyConfiguration for i, ws := range c.selectors { proxyCfg := &pbmesh.ProxyConfiguration{ - Workloads: ws, + Workloads: ws, + DynamicConfig: &pbmesh.DynamicConfig{}, } resName := fmt.Sprintf("cfg-%d", i) proxyCfgRes := resourcetest.Resource(pbmesh.ProxyConfigurationType, resName). diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go index d05887b4e71f..289c8c76548e 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/destination_multiport_test.go @@ -41,6 +41,31 @@ func TestBuildMultiportImplicitDestinations(t *testing.T) { }, } + multiportServiceData := &pbcatalog.Service{ + Ports: []*pbcatalog.ServicePort{ + { + TargetPort: "tcp", + VirtualPort: 7070, + Protocol: pbcatalog.Protocol_PROTOCOL_TCP, + }, + { + TargetPort: "tcp2", + VirtualPort: 8081, + Protocol: pbcatalog.Protocol_PROTOCOL_TCP, + }, + { + TargetPort: "http", + VirtualPort: 8080, + Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, + }, + { + TargetPort: "mesh", + VirtualPort: 20000, + Protocol: pbcatalog.Protocol_PROTOCOL_MESH, + }, + }, + } + multiportEndpointsData := &pbcatalog.ServiceEndpoints{ Endpoints: []*pbcatalog.Endpoint{ { @@ -57,12 +82,12 @@ func TestBuildMultiportImplicitDestinations(t *testing.T) { } apiAppService := resourcetest.Resource(pbcatalog.ServiceType, apiApp). WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, serviceData). + WithData(t, multiportServiceData). Build() apiApp2Service := resourcetest.Resource(pbcatalog.ServiceType, apiApp2). WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, serviceData). + WithData(t, multiportServiceData). Build() apiAppEndpoints := resourcetest.Resource(pbcatalog.ServiceEndpointsType, apiApp). diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go b/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go index 185f56c851c2..aea4360b8310 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/destinations.go @@ -94,7 +94,7 @@ func (b *Builder) buildDestination( if destination.Explicit != nil { routeName = lb.listener.Name } else { - routeName = DestinationResourceID(cpr.ParentRef.Ref) + routeName = DestinationResourceID(cpr.ParentRef.Ref, cpr.ParentRef.Port) } var ( @@ -143,6 +143,7 @@ func (b *Builder) buildDestination( b.addRoute(routeName, &pbproxystate.Route{ VirtualHosts: []*pbproxystate.VirtualHost{{ Name: routeName, + Domains: []string{"*"}, RouteRules: proxyRouteRules, }}, }) @@ -185,6 +186,7 @@ func (b *Builder) buildDestination( b.addRoute(routeName, &pbproxystate.Route{ VirtualHosts: []*pbproxystate.VirtualHost{{ Name: routeName, + Domains: []string{"*"}, RouteRules: proxyRouteRules, }}, }) @@ -287,7 +289,12 @@ func (b *Builder) buildDestination( ) clusterName := fmt.Sprintf("%s.%s", portName, sni) - egBase := b.newClusterEndpointGroup("", sni, portName, details.IdentityRefs, connectTimeout, loadBalancer) + egName := "" + + if details.FailoverConfig != nil { + egName = fmt.Sprintf("%s%d~%s", xdscommon.FailoverClusterNamePrefix, 0, clusterName) + } + egBase := b.newClusterEndpointGroup(egName, sni, portName, details.IdentityRefs, connectTimeout, loadBalancer) var endpointGroups []*pbproxystate.EndpointGroup @@ -319,7 +326,10 @@ func (b *Builder) buildDestination( destDC, b.trustDomain, ) - destClusterName := fmt.Sprintf("%s%d~%s", xdscommon.FailoverClusterNamePrefix, i, clusterName) + + // index 0 was already given to non-fail original + failoverGroupIndex := i + 1 + destClusterName := fmt.Sprintf("%s%d~%s", xdscommon.FailoverClusterNamePrefix, failoverGroupIndex, clusterName) egDest := b.newClusterEndpointGroup(destClusterName, destSNI, destPortName, destDetails.IdentityRefs, destConnectTimeout, destLoadBalancer) @@ -328,7 +338,7 @@ func (b *Builder) buildDestination( } } - b.addCluster(clusterName, endpointGroups, connectTimeout) + b.addCluster(clusterName, endpointGroups, connectTimeout, pbproxystate.Protocol(effectiveProtocol)) } return b @@ -350,6 +360,7 @@ func (b *Builder) addNullRouteCluster() *Builder { }, }, }, + Protocol: pbproxystate.Protocol_PROTOCOL_TCP, } b.proxyStateTemplate.ProxyState.Clusters[cluster.Name] = cluster @@ -393,6 +404,7 @@ func (b *Builder) addL4ClusterForDirect(clusterName string) *Builder { }, }, }, + Protocol: pbproxystate.Protocol_PROTOCOL_TCP, } b.proxyStateTemplate.ProxyState.Clusters[cluster.Name] = cluster @@ -450,6 +462,7 @@ func (b *ListenerBuilder) addL7Router(routeName string, statPrefix string, proto }, StatPrefix: statPrefix, StaticRoute: false, + Protocol: protocolMapCatalogToL7[protocol], }, } @@ -563,10 +576,12 @@ func (b *Builder) addCluster( clusterName string, endpointGroups []*pbproxystate.EndpointGroup, connectTimeout *durationpb.Duration, + protocol pbproxystate.Protocol, ) { cluster := &pbproxystate.Cluster{ Name: clusterName, AltStatName: clusterName, + Protocol: protocol, } switch len(endpointGroups) { case 0: diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go b/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go index e5baaa2cba59..991d6e6c7a87 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/expose_paths.go @@ -21,15 +21,25 @@ func (b *Builder) buildExposePaths(workload *pbcatalog.Workload) { addExposePathsRouter(exposePath). buildListener() + var protocol pbcatalog.Protocol + switch exposePath.Protocol { + case pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP: + protocol = pbcatalog.Protocol_PROTOCOL_HTTP + case pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2: + protocol = pbcatalog.Protocol_PROTOCOL_HTTP2 + default: + panic("unsupported expose paths protocol") + } + b.addExposePathsRoute(exposePath, clusterName). - addLocalAppCluster(clusterName). + addLocalAppCluster(clusterName, nil, pbproxystate.Protocol(protocol)). addLocalAppStaticEndpoints(clusterName, exposePath.LocalPathPort) } } } func (b *Builder) addExposePathsListener(workload *pbcatalog.Workload, exposePath *pbmesh.ExposePath) *ListenerBuilder { - listenerName := fmt.Sprintf("exposed_path_%s", exposePathName(exposePath)) + listenerName := exposePathListenerName(exposePath) listener := &pbproxystate.Listener{ Name: listenerName, @@ -44,7 +54,7 @@ func (b *Builder) addExposePathsListener(workload *pbcatalog.Workload, exposePat listener.BindAddress = &pbproxystate.Listener_HostPort{ HostPort: &pbproxystate.HostPortAddress{ Host: meshAddress.Host, - Port: exposePath.LocalPathPort, + Port: exposePath.ListenerPort, }, } @@ -55,7 +65,7 @@ func (b *ListenerBuilder) addExposePathsRouter(exposePath *pbmesh.ExposePath) *L if b.listener == nil { return b } - destinationName := exposePathDestinationName(exposePath) + destinationName := exposePathRouteName(exposePath) var l7Protocol pbproxystate.L7Protocol @@ -88,7 +98,7 @@ func (b *ListenerBuilder) addExposePathsRouter(exposePath *pbmesh.ExposePath) *L } func (b *Builder) addExposePathsRoute(exposePath *pbmesh.ExposePath, clusterName string) *Builder { - routeName := exposePathDestinationName(exposePath) + routeName := exposePathRouteName(exposePath) routeRule := &pbproxystate.RouteRule{ Match: &pbproxystate.RouteMatch{ PathMatch: &pbproxystate.PathMatch{ @@ -120,12 +130,22 @@ func (b *Builder) addExposePathsRoute(exposePath *pbmesh.ExposePath, clusterName func exposePathName(exposePath *pbmesh.ExposePath) string { r := regexp.MustCompile(`[^a-zA-Z0-9]+`) - return r.ReplaceAllString(exposePath.Path, "") + // The regex removes anything not a letter or number from the path. + path := r.ReplaceAllString(exposePath.Path, "") + return path +} + +func exposePathListenerName(exposePath *pbmesh.ExposePath) string { + // The path could be empty, so the unique name for this exposed path is the path and listener port. + pathPort := fmt.Sprintf("%s%d", exposePathName(exposePath), exposePath.ListenerPort) + listenerName := fmt.Sprintf("exposed_path_%s", pathPort) + return listenerName } -func exposePathDestinationName(exposePath *pbmesh.ExposePath) string { - path := exposePathName(exposePath) - return fmt.Sprintf("exposed_path_filter_%s_%d", path, exposePath.ListenerPort) +func exposePathRouteName(exposePath *pbmesh.ExposePath) string { + // The path could be empty, so the unique name for this exposed path is the path and listener port. + pathPort := fmt.Sprintf("%s%d", exposePathName(exposePath), exposePath.ListenerPort) + return fmt.Sprintf("exposed_path_route_%s", pathPort) } func exposePathClusterName(exposePath *pbmesh.ExposePath) string { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go index e6ba896b68e0..871cb444bd5d 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go @@ -6,6 +6,9 @@ package builder import ( "fmt" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "google.golang.org/protobuf/types/known/wrapperspb" + "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/envoyextensions/xdscommon" pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" @@ -31,13 +34,13 @@ func (b *Builder) BuildLocalApp(workload *pbcatalog.Workload, ctp *pbauth.Comput if port.Protocol != pbcatalog.Protocol_PROTOCOL_MESH { foundInboundNonMeshPorts = true - lb.addInboundRouter(clusterName, routeName, port, portName, trafficPermissions[portName]). + lb.addInboundRouter(clusterName, routeName, port, portName, trafficPermissions[portName], b.proxyCfg.GetDynamicConfig().GetInboundConnections()). addInboundTLS() if isL7(port.Protocol) { - b.addLocalAppRoute(routeName, clusterName) + b.addLocalAppRoute(routeName, clusterName, portName) } - b.addLocalAppCluster(clusterName). + b.addLocalAppCluster(clusterName, &portName, pbproxystate.Protocol(port.Protocol)). addLocalAppStaticEndpoints(clusterName, port.GetPort()) } } @@ -264,10 +267,16 @@ func (b *Builder) addInboundListener(name string, workload *pbcatalog.Workload) // Add TLS inspection capability to be able to parse ALPN and/or SNI information from inbound connections. listener.Capabilities = append(listener.Capabilities, pbproxystate.Capability_CAPABILITY_L4_TLS_INSPECTION) + if b.proxyCfg.GetDynamicConfig() != nil && b.proxyCfg.GetDynamicConfig().InboundConnections != nil { + listener.BalanceConnections = pbproxystate.BalanceConnections(b.proxyCfg.DynamicConfig.InboundConnections.BalanceInboundConnections) + } return b.NewListenerBuilder(listener) } -func (l *ListenerBuilder) addInboundRouter(clusterName string, routeName string, port *pbcatalog.WorkloadPort, portName string, tp *pbproxystate.TrafficPermissions) *ListenerBuilder { +func (l *ListenerBuilder) addInboundRouter(clusterName string, routeName string, + port *pbcatalog.WorkloadPort, portName string, tp *pbproxystate.TrafficPermissions, + ic *pbmesh.InboundConnectionsConfig) *ListenerBuilder { + if l.listener == nil { return l } @@ -289,13 +298,22 @@ func (l *ListenerBuilder) addInboundRouter(clusterName string, routeName string, AlpnProtocols: []string{getAlpnProtocolFromPortName(portName)}, }, } + + if ic != nil { + // MaxInboundConnections is uint32 that is used on: + // - router destinations MaxInboundConnection (uint64). + // - cluster circuit breakers UpstreamLimits.MaxConnections (uint32). + // It is cast to a uint64 here similarly as it is to the proxystateconverter code. + r.GetL4().MaxInboundConnections = uint64(ic.MaxInboundConnections) + } + l.listener.Routers = append(l.listener.Routers, r) } else if isL7(port.Protocol) { r := &pbproxystate.Router{ Destination: &pbproxystate.Router_L7{ L7: &pbproxystate.L7Destination{ StatPrefix: l.listener.Name, - Protocol: protocolMap[port.Protocol], + Protocol: protocolMapCatalogToL7[port.Protocol], TrafficPermissions: tp, StaticRoute: true, // Route name for l7 local app destinations differentiates between routes for each port. @@ -308,6 +326,13 @@ func (l *ListenerBuilder) addInboundRouter(clusterName string, routeName string, AlpnProtocols: []string{getAlpnProtocolFromPortName(portName)}, }, } + + if ic != nil { + // MaxInboundConnections is cast to a uint64 here similarly as it is to the + // as the L4 case statement above and in proxystateconverter code. + r.GetL7().MaxInboundConnections = uint64(ic.MaxInboundConnections) + } + l.listener.Routers = append(l.listener.Routers, r) } return l @@ -339,7 +364,7 @@ func getAlpnProtocolFromPortName(portName string) string { return fmt.Sprintf("consul~%s", portName) } -func (b *Builder) addLocalAppRoute(routeName string, clusterName string) { +func (b *Builder) addLocalAppRoute(routeName, clusterName, portName string) { proxyRouteRule := &pbproxystate.RouteRule{ Match: &pbproxystate.RouteMatch{ PathMatch: &pbproxystate.PathMatch{ @@ -356,6 +381,18 @@ func (b *Builder) addLocalAppRoute(routeName string, clusterName string) { }, }, } + if b.proxyCfg.GetDynamicConfig() != nil && b.proxyCfg.GetDynamicConfig().LocalConnection != nil { + lc, lcOK := b.proxyCfg.GetDynamicConfig().LocalConnection[portName] + if lcOK { + proxyRouteRule.Destination.DestinationConfiguration = + &pbproxystate.DestinationConfiguration{ + TimeoutConfig: &pbproxystate.TimeoutConfig{ + Timeout: lc.RequestTimeout, + }, + } + } + } + // Each route name for the local app is listenerName:port since there is a route per port on the local app listener. b.addRoute(routeName, &pbproxystate.Route{ VirtualHosts: []*pbproxystate.VirtualHost{{ @@ -373,9 +410,9 @@ func isL7(protocol pbcatalog.Protocol) bool { return false } -func (b *Builder) addLocalAppCluster(clusterName string) *Builder { +func (b *Builder) addLocalAppCluster(clusterName string, portName *string, protocol pbproxystate.Protocol) *Builder { // Make cluster for this router destination. - b.proxyStateTemplate.ProxyState.Clusters[clusterName] = &pbproxystate.Cluster{ + cluster := &pbproxystate.Cluster{ Group: &pbproxystate.Cluster_EndpointGroup{ EndpointGroup: &pbproxystate.EndpointGroup{ Group: &pbproxystate.EndpointGroup_Static{ @@ -383,21 +420,36 @@ func (b *Builder) addLocalAppCluster(clusterName string) *Builder { }, }, }, + Protocol: protocol, + } + + // configure inbound connections or connection timeout if either is defined + if b.proxyCfg.GetDynamicConfig() != nil && portName != nil { + lc, lcOK := b.proxyCfg.DynamicConfig.LocalConnection[*portName] + + if lcOK || b.proxyCfg.DynamicConfig.InboundConnections != nil { + cluster.GetEndpointGroup().GetStatic().Config = &pbproxystate.StaticEndpointGroupConfig{} + + if lcOK { + cluster.GetEndpointGroup().GetStatic().GetConfig().ConnectTimeout = lc.ConnectTimeout + } + + if b.proxyCfg.DynamicConfig.InboundConnections != nil { + cluster.GetEndpointGroup().GetStatic().GetConfig().CircuitBreakers = &pbproxystate.CircuitBreakers{ + UpstreamLimits: &pbproxystate.UpstreamLimits{ + MaxConnections: &wrapperspb.UInt32Value{Value: b.proxyCfg.DynamicConfig.InboundConnections.MaxInboundConnections}, + }, + } + } + } } + + b.proxyStateTemplate.ProxyState.Clusters[clusterName] = cluster return b } func (b *Builder) addBlackHoleCluster() *Builder { - b.proxyStateTemplate.ProxyState.Clusters[xdscommon.BlackHoleClusterName] = &pbproxystate.Cluster{ - Group: &pbproxystate.Cluster_EndpointGroup{ - EndpointGroup: &pbproxystate.EndpointGroup{ - Group: &pbproxystate.EndpointGroup_Static{ - Static: &pbproxystate.StaticEndpointGroup{}, - }, - }, - }, - } - return b + return b.addLocalAppCluster(xdscommon.BlackHoleClusterName, nil, pbproxystate.Protocol_PROTOCOL_TCP) } func (b *Builder) addLocalAppStaticEndpoints(clusterName string, port uint32) { @@ -441,7 +493,7 @@ func (l *ListenerBuilder) addInboundTLS() *ListenerBuilder { return l } -var protocolMap = map[pbcatalog.Protocol]pbproxystate.L7Protocol{ +var protocolMapCatalogToL7 = map[pbcatalog.Protocol]pbproxystate.L7Protocol{ pbcatalog.Protocol_PROTOCOL_HTTP: pbproxystate.L7Protocol_L7_PROTOCOL_HTTP, pbcatalog.Protocol_PROTOCOL_HTTP2: pbproxystate.L7Protocol_L7_PROTOCOL_HTTP2, pbcatalog.Protocol_PROTOCOL_GRPC: pbproxystate.L7Protocol_L7_PROTOCOL_GRPC, 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 785e0aab2e2e..33dcab715522 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go @@ -4,7 +4,10 @@ package builder import ( + "google.golang.org/protobuf/types/known/durationpb" + "sort" "testing" + "time" "github.com/stretchr/testify/require" @@ -139,6 +142,55 @@ func TestBuildLocalApp_WithProxyConfiguration(t *testing.T) { }, }, }, + // source/local-and-inbound-connections shows that configuring LocalCOnnection + // and InboundConnections in DynamicConfig will set fields on standard clusters and routes, + // but will not set fields on exposed path clusters and routes. + "source/local-and-inbound-connections": { + workload: &pbcatalog.Workload{ + Addresses: []*pbcatalog.WorkloadAddress{ + { + Host: "10.0.0.1", + }, + }, + Ports: map[string]*pbcatalog.WorkloadPort{ + "port1": {Port: 8080, Protocol: pbcatalog.Protocol_PROTOCOL_TCP}, + "port2": {Port: 20000, Protocol: pbcatalog.Protocol_PROTOCOL_MESH}, + "port3": {Port: 8081, Protocol: pbcatalog.Protocol_PROTOCOL_HTTP}, + }, + }, + proxyCfg: &pbmesh.ComputedProxyConfiguration{ + DynamicConfig: &pbmesh.DynamicConfig{ + LocalConnection: map[string]*pbmesh.ConnectionConfig{ + "port1": { + ConnectTimeout: durationpb.New(6 * time.Second), + RequestTimeout: durationpb.New(7 * time.Second)}, + "port3": { + ConnectTimeout: durationpb.New(8 * time.Second), + RequestTimeout: durationpb.New(9 * time.Second)}, + }, + InboundConnections: &pbmesh.InboundConnectionsConfig{ + MaxInboundConnections: 123, + BalanceInboundConnections: pbmesh.BalanceConnections(pbproxystate.BalanceConnections_BALANCE_CONNECTIONS_EXACT), + }, + ExposeConfig: &pbmesh.ExposeConfig{ + ExposePaths: []*pbmesh.ExposePath{ + { + ListenerPort: 1234, + Path: "/health", + LocalPathPort: 9090, + Protocol: pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP, + }, + { + ListenerPort: 1235, + Path: "GetHealth", + LocalPathPort: 9091, + Protocol: pbmesh.ExposePathProtocol_EXPOSE_PATH_PROTOCOL_HTTP2, + }, + }, + }, + }, + }, + }, } for name, c := range cases { @@ -146,10 +198,24 @@ func TestBuildLocalApp_WithProxyConfiguration(t *testing.T) { proxyTmpl := New(testProxyStateTemplateID(), testIdentityRef(), "foo.consul", "dc1", true, c.proxyCfg). BuildLocalApp(c.workload, nil). 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 := golden.Get(t, actual, name+".golden") + expected := JSONToProxyTemplate(t, golden.GetBytes(t, actual, name+".golden")) - require.JSONEq(t, expected, actual) + // 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)) }) } } diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/naming.go b/internal/mesh/internal/controllers/sidecarproxy/builder/naming.go index 31eba2e7ce88..13a21e4e597d 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/naming.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/naming.go @@ -29,7 +29,7 @@ func DestinationStatPrefix(serviceRef *pbresource.Reference, portName, datacente } func DestinationListenerName(destinationRef *pbresource.Reference, portName string, address string, port uint32) string { - name := fmt.Sprintf("%s:%s:%s", DestinationResourceID(destinationRef), portName, address) + name := fmt.Sprintf("%s:%s", DestinationResourceID(destinationRef, portName), address) if port != 0 { return fmt.Sprintf("%s:%d", name, port) } @@ -39,8 +39,8 @@ func DestinationListenerName(destinationRef *pbresource.Reference, portName stri // DestinationResourceID returns a string representation that uniquely identifies the // upstream in a canonical but human readable way. -func DestinationResourceID(destinationRef *pbresource.Reference) string { +func DestinationResourceID(destinationRef *pbresource.Reference, port string) string { tenancyPrefix := fmt.Sprintf("%s/%s/%s", destinationRef.Tenancy.Partition, destinationRef.Tenancy.PeerName, destinationRef.Tenancy.Namespace) - return fmt.Sprintf("%s/%s", tenancyPrefix, destinationRef.Name) + return fmt.Sprintf("%s/%s:%s", tenancyPrefix, destinationRef.Name, port) } diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/routes.go b/internal/mesh/internal/controllers/sidecarproxy/builder/routes.go index b5c8fafebbbb..03d68bdf081a 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/routes.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/routes.go @@ -473,6 +473,12 @@ func makeGRPCRouteMatch(match *pbmesh.GRPCRouteMatch) *pbproxystate.RouteMatch { default: panic(fmt.Sprintf("unknown method match type: %v", match.Method.Type)) } + } else { + em.PathMatch = &pbproxystate.PathMatch{ + PathMatch: &pbproxystate.PathMatch_Prefix{ + Prefix: "/", + }, + } } em.HeaderMatches = translateHeaderMatches(match.Headers, nil) diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden index 322ea928f42b..098beac1af9b 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden @@ -9,7 +9,8 @@ } } }, - "name": "original-destination" + "name": "original-destination", + "protocol": "PROTOCOL_TCP" }, "tcp.api-1.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", @@ -36,7 +37,8 @@ } } }, - "name": "tcp.api-1.default.dc1.internal.foo.consul" + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, "tcp.api-2.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", @@ -63,7 +65,8 @@ } } }, - "name": "tcp.api-2.default.dc1.internal.foo.consul" + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden index eb7c3e60fcd4..1f925e4b5a2b 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multi-destination.golden @@ -9,7 +9,8 @@ } } }, - "name": "null_route_cluster" + "name": "null_route_cluster", + "protocol": "PROTOCOL_TCP" }, "tcp.api-1.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", @@ -36,7 +37,8 @@ } } }, - "name": "tcp.api-1.default.dc1.internal.foo.consul" + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, "tcp.api-2.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", @@ -63,7 +65,8 @@ } } }, - "name": "tcp.api-2.default.dc1.internal.foo.consul" + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, "tcp2.api-1.default.dc1.internal.foo.consul": { "altStatName": "tcp2.api-1.default.dc1.internal.foo.consul", @@ -90,7 +93,8 @@ } } }, - "name": "tcp2.api-1.default.dc1.internal.foo.consul" + "name": "tcp2.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, "tcp2.api-2.default.dc1.internal.foo.consul": { "altStatName": "tcp2.api-2.default.dc1.internal.foo.consul", @@ -117,7 +121,8 @@ } } }, - "name": "tcp2.api-2.default.dc1.internal.foo.consul" + "name": "tcp2.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden index 7f2fe6383d12..e00c9d08e010 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden @@ -9,7 +9,8 @@ } } }, - "name": "original-destination" + "name": "original-destination", + "protocol": "PROTOCOL_TCP" }, "tcp.api-1.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", @@ -36,7 +37,8 @@ } } }, - "name": "tcp.api-1.default.dc1.internal.foo.consul" + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, "tcp.api-2.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", @@ -63,7 +65,8 @@ } } }, - "name": "tcp.api-2.default.dc1.internal.foo.consul" + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address.golden index 7ba711123559..ae2d99c94261 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-ip-port-bind-address.golden @@ -9,7 +9,8 @@ } } }, - "name": "null_route_cluster" + "name": "null_route_cluster", + "protocol": "PROTOCOL_TCP" }, "tcp.api-1.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", @@ -36,7 +37,8 @@ } } }, - "name": "tcp.api-1.default.dc1.internal.foo.consul" + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, "tcp.api-2.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", @@ -63,7 +65,8 @@ } } }, - "name": "tcp.api-2.default.dc1.internal.foo.consul" + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address.golden index ca72e84ef73c..2af48e9f29e3 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-destination-unix-socket-bind-address.golden @@ -26,7 +26,8 @@ } } }, - "name": "tcp.api-2.default.dc1.internal.foo.consul" + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy.golden index 719d461c27df..50e871481174 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/destination/l4-single-implicit-destination-tproxy.golden @@ -9,7 +9,8 @@ } } }, - "name": "original-destination" + "name": "original-destination", + "protocol": "PROTOCOL_TCP" }, "tcp.api-1.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", @@ -36,7 +37,8 @@ } } }, - "name": "tcp.api-1.default.dc1.internal.foo.consul" + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { 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 77f4181c317f..ca69db7dfcb0 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 @@ -30,7 +30,8 @@ } } } - } + }, + "name": "failover-target~0~http.api-1.default.dc1.internal.foo.consul" }, { "dynamic": { @@ -54,11 +55,12 @@ } } }, - "name": "failover-target~0~http.api-1.default.dc1.internal.foo.consul" + "name": "failover-target~1~http.api-1.default.dc1.internal.foo.consul" } ] }, - "name": "http.api-1.default.dc1.internal.foo.consul" + "name": "http.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" }, "http.api-2.default.dc1.internal.foo.consul": { "altStatName": "http.api-2.default.dc1.internal.foo.consul", @@ -85,7 +87,8 @@ } } }, - "name": "http.api-2.default.dc1.internal.foo.consul" + "name": "http.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" }, "null_route_cluster": { "endpointGroup": { @@ -95,7 +98,8 @@ } } }, - "name": "null_route_cluster" + "name": "null_route_cluster", + "protocol": "PROTOCOL_TCP" }, "tcp.api-1.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", @@ -122,7 +126,8 @@ } } }, - "name": "tcp.api-1.default.dc1.internal.foo.consul" + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, "tcp.api-2.default.dc1.internal.foo.consul": { "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", @@ -149,7 +154,8 @@ } } }, - "name": "tcp.api-2.default.dc1.internal.foo.consul" + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { @@ -238,6 +244,9 @@ "default/local/default/api-1:http:1.1.1.1:1234": { "virtualHosts": [ { + "domains": [ + "*" + ], "name": "default/local/default/api-1:http:1.1.1.1:1234", "routeRules": [ { @@ -310,7 +319,7 @@ } }, "requiredEndpoints": { - "failover-target~0~http.api-1.default.dc1.internal.foo.consul": { + "failover-target~1~http.api-1.default.dc1.internal.foo.consul": { "id": { "name": "backup-1", "tenancy": { 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 7fe5d2850c56..3192629710d9 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,10 +26,11 @@ } } }, - "name": "http.api-app.default.dc1.internal.foo.consul" + "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": { @@ -38,7 +39,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~http" + "consul~tcp2" ], "outboundMesh": { "identityKey": "test-identity", @@ -53,20 +54,11 @@ } } }, - "name": "http.api-app2.default.dc1.internal.foo.consul" + "name": "tcp2.api-app2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination" - }, - "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": { @@ -75,7 +67,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp" + "consul~http" ], "outboundMesh": { "identityKey": "test-identity", @@ -90,10 +82,11 @@ } } }, - "name": "tcp.api-app.default.dc1.internal.foo.consul" + "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": { @@ -102,7 +95,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp" + "consul~http" ], "outboundMesh": { "identityKey": "test-identity", @@ -117,10 +110,22 @@ } } }, - "name": "tcp.api-app2.default.dc1.internal.foo.consul" + "name": "http.api-app2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -129,7 +134,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp2" + "consul~tcp" ], "outboundMesh": { "identityKey": "test-identity", @@ -144,10 +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": { @@ -156,7 +162,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp2" + "consul~tcp" ], "outboundMesh": { "identityKey": "test-identity", @@ -171,7 +177,8 @@ } } }, - "name": "tcp2.api-app2.default.dc1.internal.foo.consul" + "name": "tcp.api-app2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { @@ -248,7 +255,7 @@ { "l7": { "route": { - "name": "default/local/default/api-app" + "name": "default/local/default/api-app:http" }, "statPrefix": "upstream." }, @@ -265,7 +272,7 @@ { "l7": { "route": { - "name": "default/local/default/api-app2" + "name": "default/local/default/api-app2:http" }, "statPrefix": "upstream." }, @@ -325,15 +332,18 @@ } ], "routes": { - "default/local/default/api-app": { + "default/local/default/api-app2:http": { "virtualHosts": [ { - "name": "default/local/default/api-app", + "domains": [ + "*" + ], + "name": "default/local/default/api-app2:http", "routeRules": [ { "destination": { "cluster": { - "name": "http.api-app.default.dc1.internal.foo.consul" + "name": "http.api-app2.default.dc1.internal.foo.consul" } }, "match": { @@ -346,15 +356,18 @@ } ] }, - "default/local/default/api-app2": { + "default/local/default/api-app:http": { "virtualHosts": [ { - "name": "default/local/default/api-app2", + "domains": [ + "*" + ], + "name": "default/local/default/api-app:http", "routeRules": [ { "destination": { "cluster": { - "name": "http.api-app2.default.dc1.internal.foo.consul" + "name": "http.api-app.default.dc1.internal.foo.consul" } }, "match": { @@ -370,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": { @@ -386,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": { @@ -402,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": { @@ -418,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": { @@ -434,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": { @@ -450,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 cdf1275e0d68..2ab840e3da9b 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,20 +26,11 @@ } } }, - "name": "http.api-app.default.dc1.internal.foo.consul" + "name": "tcp2.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination" - }, - "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": { @@ -48,7 +39,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp" + "consul~http" ], "outboundMesh": { "identityKey": "test-identity", @@ -63,10 +54,22 @@ } } }, - "name": "tcp.api-app.default.dc1.internal.foo.consul" + "name": "http.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -75,7 +78,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp2" + "consul~tcp" ], "outboundMesh": { "identityKey": "test-identity", @@ -90,7 +93,8 @@ } } }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul" + "name": "tcp.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { @@ -146,7 +150,7 @@ { "l7": { "route": { - "name": "default/local/default/api-app" + "name": "default/local/default/api-app:http" }, "statPrefix": "upstream." }, @@ -181,10 +185,13 @@ } ], "routes": { - "default/local/default/api-app": { + "default/local/default/api-app:http": { "virtualHosts": [ { - "name": "default/local/default/api-app", + "domains": [ + "*" + ], + "name": "default/local/default/api-app:http", "routeRules": [ { "destination": { @@ -205,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": { @@ -221,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": { @@ -237,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 cdf1275e0d68..2ab840e3da9b 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,20 +26,11 @@ } } }, - "name": "http.api-app.default.dc1.internal.foo.consul" + "name": "tcp2.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" }, - "original-destination": { - "endpointGroup": { - "passthrough": { - "config": { - "connectTimeout": "5s" - } - } - }, - "name": "original-destination" - }, - "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": { @@ -48,7 +39,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp" + "consul~http" ], "outboundMesh": { "identityKey": "test-identity", @@ -63,10 +54,22 @@ } } }, - "name": "tcp.api-app.default.dc1.internal.foo.consul" + "name": "http.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" }, - "tcp2.api-app.default.dc1.internal.foo.consul": { - "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", "endpointGroup": { "dynamic": { "config": { @@ -75,7 +78,7 @@ }, "outboundTls": { "alpnProtocols": [ - "consul~tcp2" + "consul~tcp" ], "outboundMesh": { "identityKey": "test-identity", @@ -90,7 +93,8 @@ } } }, - "name": "tcp2.api-app.default.dc1.internal.foo.consul" + "name": "tcp.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" } }, "identity": { @@ -146,7 +150,7 @@ { "l7": { "route": { - "name": "default/local/default/api-app" + "name": "default/local/default/api-app:http" }, "statPrefix": "upstream." }, @@ -181,10 +185,13 @@ } ], "routes": { - "default/local/default/api-app": { + "default/local/default/api-app:http": { "virtualHosts": [ { - "name": "default/local/default/api-app", + "domains": [ + "*" + ], + "name": "default/local/default/api-app:http", "routeRules": [ { "destination": { @@ -205,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": { @@ -221,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": { @@ -237,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 index 8551d50dcc88..95ee222f3d26 100644 --- 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 @@ -5,7 +5,8 @@ "endpointGroup": { "static": {} }, - "name": "local_app:port1" + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" } }, "endpoints": { 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 index 1c7d58988f6d..0cb52d992155 100644 --- 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 @@ -5,7 +5,8 @@ "endpointGroup": { "static": {} }, - "name": "local_app:port1" + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" } }, "endpoints": { 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 index 1c7d58988f6d..0cb52d992155 100644 --- 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 @@ -5,7 +5,8 @@ "endpointGroup": { "static": {} }, - "name": "local_app:port1" + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" } }, "endpoints": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden index df8af168212d..2af5ce9c06d4 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/l7-expose-paths.golden @@ -5,19 +5,22 @@ "endpointGroup": { "static": {} }, - "name": "exposed_cluster_9090" + "name": "exposed_cluster_9090", + "protocol": "PROTOCOL_HTTP" }, "exposed_cluster_9091": { "endpointGroup": { "static": {} }, - "name": "exposed_cluster_9091" + "name": "exposed_cluster_9091", + "protocol": "PROTOCOL_HTTP2" }, "local_app:port1": { "endpointGroup": { "static": {} }, - "name": "local_app:port1" + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" } }, "endpoints": { @@ -107,16 +110,16 @@ "direction": "DIRECTION_INBOUND", "hostPort": { "host": "10.0.0.1", - "port": 9090 + "port": 1234 }, - "name": "exposed_path_health", + "name": "exposed_path_health1234", "routers": [ { "l7": { "route": { - "name": "exposed_path_filter_health_1234" + "name": "exposed_path_route_health1234" }, - "statPrefix": "exposed_path_filter_health_1234", + "statPrefix": "exposed_path_route_health1234", "staticRoute": true } } @@ -126,17 +129,17 @@ "direction": "DIRECTION_INBOUND", "hostPort": { "host": "10.0.0.1", - "port": 9091 + "port": 1235 }, - "name": "exposed_path_GetHealth", + "name": "exposed_path_GetHealth1235", "routers": [ { "l7": { "protocol": "L7_PROTOCOL_HTTP2", "route": { - "name": "exposed_path_filter_GetHealth_1235" + "name": "exposed_path_route_GetHealth1235" }, - "statPrefix": "exposed_path_filter_GetHealth_1235", + "statPrefix": "exposed_path_route_GetHealth1235", "staticRoute": true } } @@ -144,13 +147,13 @@ } ], "routes": { - "exposed_path_filter_GetHealth_1235": { + "exposed_path_route_GetHealth1235": { "virtualHosts": [ { "domains": [ "*" ], - "name": "exposed_path_filter_GetHealth_1235", + "name": "exposed_path_route_GetHealth1235", "routeRules": [ { "destination": { @@ -168,13 +171,13 @@ } ] }, - "exposed_path_filter_health_1234": { + "exposed_path_route_health1234": { "virtualHosts": [ { "domains": [ "*" ], - "name": "exposed_path_filter_health_1234", + "name": "exposed_path_route_health1234", "routeRules": [ { "destination": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections.golden new file mode 100644 index 000000000000..299b051ef69d --- /dev/null +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/local-and-inbound-connections.golden @@ -0,0 +1,304 @@ +{ + "proxyState": { + "clusters": { + "exposed_cluster_9090": { + "endpointGroup": { + "static": {} + }, + "name": "exposed_cluster_9090", + "protocol": "PROTOCOL_HTTP" + }, + "exposed_cluster_9091": { + "endpointGroup": { + "static": {} + }, + "name": "exposed_cluster_9091", + "protocol": "PROTOCOL_HTTP2" + }, + "local_app:port1": { + "endpointGroup": { + "static": { + "config": { + "circuitBreakers": { + "upstreamLimits": { + "maxConnections": 123 + } + }, + "connectTimeout": "6s" + } + } + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + }, + "local_app:port3": { + "endpointGroup": { + "static": { + "config": { + "circuitBreakers": { + "upstreamLimits": { + "maxConnections": 123 + } + }, + "connectTimeout": "8s" + } + } + }, + "name": "local_app:port3", + "protocol": "PROTOCOL_HTTP" + } + }, + "endpoints": { + "exposed_cluster_9090": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + }, + "exposed_cluster_9091": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9091 + } + } + ] + }, + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + }, + "local_app:port3": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8081 + } + } + ] + } + }, + "identity": { + "name": "test-identity", + "tenancy": { + "namespace": "default", + "partition": "default", + "peerName": "local" + }, + "type": { + "group": "auth", + "groupVersion": "v2beta1", + "kind": "WorkloadIdentity" + } + }, + "listeners": [ + { + "balanceConnections": "BALANCE_CONNECTIONS_EXACT", + "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" + }, + "maxInboundConnections": "123", + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l7": { + "maxInboundConnections": "123", + "route": { + "name": "public_listener:port3" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port3" + ] + } + } + ] + }, + { + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 1234 + }, + "name": "exposed_path_health1234", + "routers": [ + { + "l7": { + "route": { + "name": "exposed_path_route_health1234" + }, + "statPrefix": "exposed_path_route_health1234", + "staticRoute": true + } + } + ] + }, + { + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 1235 + }, + "name": "exposed_path_GetHealth1235", + "routers": [ + { + "l7": { + "protocol": "L7_PROTOCOL_HTTP2", + "route": { + "name": "exposed_path_route_GetHealth1235" + }, + "statPrefix": "exposed_path_route_GetHealth1235", + "staticRoute": true + } + } + ] + } + ], + "routes": { + "exposed_path_route_GetHealth1235": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "exposed_path_route_GetHealth1235", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "exposed_cluster_9091" + } + }, + "match": { + "pathMatch": { + "exact": "GetHealth" + } + } + } + ] + } + ] + }, + "exposed_path_route_health1234": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "exposed_path_route_health1234", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "exposed_cluster_9090" + } + }, + "match": { + "pathMatch": { + "exact": "/health" + } + } + } + ] + } + ] + }, + "public_listener:port3": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:port3", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:port3" + }, + "destinationConfiguration": { + "timeoutConfig": { + "timeout": "9s" + } + } + }, + "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/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden index b4ef8b93dd1d..93a69b2bb033 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden @@ -5,13 +5,15 @@ "endpointGroup": { "static": {} }, - "name": "local_app:admin-port" + "name": "local_app:admin-port", + "protocol": "PROTOCOL_TCP" }, "local_app:api-port": { "endpointGroup": { "static": {} }, - "name": "local_app:api-port" + "name": "local_app:api-port", + "protocol": "PROTOCOL_TCP" } }, "endpoints": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden index 9df4452174b5..3831349ccdbd 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden @@ -5,13 +5,15 @@ "endpointGroup": { "static": {} }, - "name": "local_app:admin-port" + "name": "local_app:admin-port", + "protocol": "PROTOCOL_TCP" }, "local_app:api-port": { "endpointGroup": { "static": {} }, - "name": "local_app:api-port" + "name": "local_app:api-port", + "protocol": "PROTOCOL_TCP" } }, "endpoints": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports.golden index 9df4452174b5..3831349ccdbd 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-single-workload-address-without-ports.golden @@ -5,13 +5,15 @@ "endpointGroup": { "static": {} }, - "name": "local_app:admin-port" + "name": "local_app:admin-port", + "protocol": "PROTOCOL_TCP" }, "local_app:api-port": { "endpointGroup": { "static": {} }, - "name": "local_app:api-port" + "name": "local_app:api-port", + "protocol": "PROTOCOL_TCP" } }, "endpoints": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port.golden index eb3b84dd9839..dc9afc44fa43 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l4-workload-with-only-mesh-port.golden @@ -5,7 +5,8 @@ "endpointGroup": { "static": {} }, - "name": "black-hole-cluster" + "name": "black-hole-cluster", + "protocol": "PROTOCOL_TCP" } }, "identity": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden index 7afae2c4d3b9..dcba1dc58150 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden @@ -5,13 +5,15 @@ "endpointGroup": { "static": {} }, - "name": "local_app:admin-port" + "name": "local_app:admin-port", + "protocol": "PROTOCOL_HTTP" }, "local_app:api-port": { "endpointGroup": { "static": {} }, - "name": "local_app:api-port" + "name": "local_app:api-port", + "protocol": "PROTOCOL_HTTP2" } }, "endpoints": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden index d65cc6eb2dd3..08d9faa234ea 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden @@ -5,19 +5,22 @@ "endpointGroup": { "static": {} }, - "name": "local_app:admin-port" + "name": "local_app:admin-port", + "protocol": "PROTOCOL_HTTP" }, "local_app:api-port": { "endpointGroup": { "static": {} }, - "name": "local_app:api-port" + "name": "local_app:api-port", + "protocol": "PROTOCOL_HTTP2" }, "local_app:grpc-port": { "endpointGroup": { "static": {} }, - "name": "local_app:grpc-port" + "name": "local_app:grpc-port", + "protocol": "PROTOCOL_GRPC" } }, "endpoints": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports.golden index d65cc6eb2dd3..08d9faa234ea 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiport-l7-single-workload-address-without-ports.golden @@ -5,19 +5,22 @@ "endpointGroup": { "static": {} }, - "name": "local_app:admin-port" + "name": "local_app:admin-port", + "protocol": "PROTOCOL_HTTP" }, "local_app:api-port": { "endpointGroup": { "static": {} }, - "name": "local_app:api-port" + "name": "local_app:api-port", + "protocol": "PROTOCOL_HTTP2" }, "local_app:grpc-port": { "endpointGroup": { "static": {} }, - "name": "local_app:grpc-port" + "name": "local_app:grpc-port", + "protocol": "PROTOCOL_GRPC" } }, "endpoints": { diff --git a/internal/mesh/internal/controllers/sidecarproxy/controller_test.go b/internal/mesh/internal/controllers/sidecarproxy/controller_test.go index 883984f1615d..0d6684f0ef54 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/controller_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/controller_test.go @@ -553,7 +553,7 @@ func (suite *controllerTestSuite) TestController() { }).Write(suite.T(), suite.client) testutil.RunStep(suite.T(), "add explicit destinations and check that new proxy state is generated", func(t *testing.T) { - webProxyStateTemplate = suite.client.WaitForNewVersion(t, webProxyStateTemplateID, webProxyStateTemplate.Version) + webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) requireExplicitDestinationsFound(t, "api", webProxyStateTemplate) }) @@ -613,7 +613,7 @@ func (suite *controllerTestSuite) TestController() { }) // We should get a new web proxy template resource because this destination should be removed. - webProxyStateTemplate = suite.client.WaitForNewVersion(t, webProxyStateTemplateID, webProxyStateTemplate.Version) + webProxyStateTemplate = suite.client.WaitForNewVersion(suite.T(), webProxyStateTemplateID, webProxyStateTemplate.Version) requireExplicitDestinationsNotFound(t, "api", webProxyStateTemplate) }) diff --git a/internal/mesh/internal/controllers/xds/controller_test.go b/internal/mesh/internal/controllers/xds/controller_test.go index 6bb5f85c9908..e1dd0ebb6171 100644 --- a/internal/mesh/internal/controllers/xds/controller_test.go +++ b/internal/mesh/internal/controllers/xds/controller_test.go @@ -7,10 +7,14 @@ import ( "context" "crypto/x509" "encoding/pem" + "fmt" + "strings" "testing" + "github.com/hashicorp/consul/internal/testing/golden" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "google.golang.org/protobuf/encoding/protojson" svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing" "github.com/hashicorp/consul/agent/leafcert" @@ -995,3 +999,167 @@ func (suite *xdsControllerTestSuite) TestReconcile_prevWatchesToCancel() { func TestXdsController(t *testing.T) { suite.Run(t, new(xdsControllerTestSuite)) } + +// TestReconcile_SidecarProxyGoldenFileInputs tests the Reconcile() by using +// the golden test output/expected files from the sidecar proxy tests as inputs +// to the XDS controller reconciliation. +// XDS controller reconciles the full ProxyStateTemplate object. The fields +// that things that it focuses on are leaf certs, endpoints, and trust bundles, +// which is just a subset of the ProxyStateTemplate struct. Prior to XDS controller +// reconciliation, the sidecar proxy controller will have reconciled the other parts +// of the ProxyStateTemplate. +// Since the XDS controller does act on the ProxyStateTemplate, the tests +// utilize that entire object rather than just the parts that XDS controller +// internals reconciles. Namely, by using checking the full ProxyStateTemplate +// rather than just endpoints, leaf certs, and trust bundles, the test also ensures +// side effects or change in scope to XDS controller are not introduce mistakenly. +func (suite *xdsControllerTestSuite) TestReconcile_SidecarProxyGoldenFileInputs() { + path := "../sidecarproxy/builder/testdata" + cases := []string{ + // destinations - please add in alphabetical order + "destination/l4-single-destination-ip-port-bind-address", + "destination/l4-single-destination-unix-socket-bind-address", + "destination/l4-single-implicit-destination-tproxy", + "destination/l4-multi-destination", + "destination/l4-multiple-implicit-destinations-tproxy", + "destination/l4-implicit-and-explicit-destinations-tproxy", + "destination/mixed-multi-destination", + "destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy", + "destination/multiport-l4-and-l7-single-implicit-destination-tproxy", + "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/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", + } + + for _, name := range cases { + suite.Run(name, func() { + // Create ProxyStateTemplate from the golden file. + pst := JSONToProxyTemplate(suite.T(), + golden.GetBytesAtFilePath(suite.T(), fmt.Sprintf("%s/%s.golden", path, name))) + + // Destinations will need endpoint refs set up. + if strings.Split(name, "/")[0] == "destination" && len(pst.ProxyState.Endpoints) == 0 { + suite.addRequiredEndpointsAndRefs(pst) + } + + // Store the initial ProxyStateTemplate. + proxyStateTemplate := resourcetest.Resource(pbmesh.ProxyStateTemplateType, "test"). + WithData(suite.T(), pst). + Write(suite.T(), suite.client) + + // Check with resource service that it exists. + retry.Run(suite.T(), func(r *retry.R) { + suite.client.RequireResourceExists(r, proxyStateTemplate.Id) + }) + + // Track it in the mapper. + suite.mapper.TrackItem(proxyStateTemplate.Id, []resource.ReferenceOrID{}) + + // Run the reconcile, and since no ProxyStateTemplate is stored, this simulates a deletion. + err := suite.ctl.Reconcile(context.Background(), suite.runtime, controller.Request{ + ID: proxyStateTemplate.Id, + }) + require.NoError(suite.T(), err) + require.NotNil(suite.T(), proxyStateTemplate) + + // Get the reconciled proxyStateTemplate to check the reconcile results. + reconciledPS := suite.updater.Get(proxyStateTemplate.Id.Name) + + // Verify leaf cert contents then hard code them for comparison + // and downstream tests since they change from test run to test run. + require.NotEmpty(suite.T(), reconciledPS.LeafCertificates) + reconciledPS.LeafCertificates = map[string]*pbproxystate.LeafCertificate{ + "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", + }, + } + + // Compare actual vs expected. + actual := prototest.ProtoToJSON(suite.T(), reconciledPS) + expected := golden.Get(suite.T(), actual, name+".golden") + require.JSONEq(suite.T(), expected, actual) + }) + } +} + +func (suite *xdsControllerTestSuite) addRequiredEndpointsAndRefs(pst *pbmesh.ProxyStateTemplate) { + //get service data + serviceData := &pbcatalog.Service{} + var vp uint32 = 7000 + requiredEps := make(map[string]*pbproxystate.EndpointRef) + + // iterate through clusters and set up endpoints for cluster/mesh port. + for clusterName := range pst.ProxyState.Clusters { + if clusterName == "null_route_cluster" || clusterName == "original-destination" { + continue + } + + //increment the random port number. + vp++ + clusterNameSplit := strings.Split(clusterName, ".") + port := clusterNameSplit[0] + svcName := clusterNameSplit[1] + + // set up service data with port info. + serviceData.Ports = append(serviceData.Ports, &pbcatalog.ServicePort{ + TargetPort: port, + VirtualPort: vp, + Protocol: pbcatalog.Protocol_PROTOCOL_TCP, + }) + + // create service. + svc := resourcetest.Resource(pbcatalog.ServiceType, svcName). + WithData(suite.T(), &pbcatalog.Service{}). + Write(suite.T(), suite.client) + + // create endpoints with svc as owner. + eps := resourcetest.Resource(pbcatalog.ServiceEndpointsType, svcName). + WithData(suite.T(), &pbcatalog.ServiceEndpoints{Endpoints: []*pbcatalog.Endpoint{ + { + Ports: map[string]*pbcatalog.WorkloadPort{ + "mesh": { + Port: 20000, + Protocol: pbcatalog.Protocol_PROTOCOL_MESH, + }, + }, + Addresses: []*pbcatalog.WorkloadAddress{ + { + Host: "10.1.1.1", + Ports: []string{"mesh"}, + }, + }, + }, + }}). + WithOwner(svc.Id). + Write(suite.T(), suite.client) + + // add to working list of required endpoints. + requiredEps[clusterName] = &pbproxystate.EndpointRef{ + Id: eps.Id, + Port: "mesh", + } + } + + // set working list of required endpoints as proxy state's RequiredEndpoints. + pst.RequiredEndpoints = requiredEps +} + +func JSONToProxyTemplate(t *testing.T, json []byte) *pbmesh.ProxyStateTemplate { + t.Helper() + proxyTemplate := &pbmesh.ProxyStateTemplate{} + m := protojson.UnmarshalOptions{} + err := m.Unmarshal(json, proxyTemplate) + require.NoError(t, err) + return proxyTemplate +} diff --git a/internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden new file mode 100644 index 000000000000..dd425312053b --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/l4-implicit-and-explicit-destinations-tproxy.golden @@ -0,0 +1,185 @@ +{ + "clusters": { + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "tcp.api-1.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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": [ + { + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "1.1.1.1", + "port": 1234 + }, + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-1.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-1.default.default.dc1" + } + } + ] + }, + { + "capabilities": [ + "CAPABILITY_TRANSPARENT" + ], + "defaultRouter": { + "l4": { + "cluster": { + "name": "original-destination" + }, + "statPrefix": "upstream.original-destination" + } + }, + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "127.0.0.1", + "port": 15001 + }, + "name": "outbound_listener", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-2.default.default.dc1" + }, + "match": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + } + } + ] + } + ], + "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/destination/l4-multi-destination.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination.golden new file mode 100644 index 000000000000..70448ca45048 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/l4-multi-destination.golden @@ -0,0 +1,301 @@ +{ + "clusters": { + "null_route_cluster": { + "endpointGroup": { + "static": { + "config": { + "connectTimeout": "10s" + } + } + }, + "name": "null_route_cluster", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp2.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp2.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "tcp.api-1.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp2.api-1.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp2.api-2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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": [ + { + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "1.1.1.1", + "port": 1234 + }, + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "routers": [ + { + "l4": { + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + }, + { + "direction": "DIRECTION_OUTBOUND", + "name": "default/local/default/api-2:tcp:/path/to/socket", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-2.default.default.dc1" + } + } + ], + "unixSocket": { + "mode": "0666", + "path": "/path/to/socket" + } + }, + { + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "1.1.1.1", + "port": 2345 + }, + "name": "default/local/default/api-1:tcp2:1.1.1.1:2345", + "routers": [ + { + "l4": { + "statPrefix": "upstream.tcp2.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp2.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp2.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + }, + { + "direction": "DIRECTION_OUTBOUND", + "name": "default/local/default/api-2:tcp2:/path/to/socket", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp2.api-2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-2.default.default.dc1" + } + } + ], + "unixSocket": { + "mode": "0666", + "path": "/path/to/socket" + } + } + ], + "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/destination/l4-multiple-implicit-destinations-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden new file mode 100644 index 000000000000..24c917a4d338 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/l4-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,184 @@ +{ + "clusters": { + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "tcp.api-1.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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_TRANSPARENT" + ], + "defaultRouter": { + "l4": { + "cluster": { + "name": "original-destination" + }, + "statPrefix": "upstream.original-destination" + } + }, + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "127.0.0.1", + "port": 15001 + }, + "name": "outbound_listener", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-1.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-1.default.default.dc1" + }, + "match": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l4": { + "cluster": { + "name": "tcp.api-2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-2.default.default.dc1" + }, + "match": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + } + } + ] + } + ], + "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/destination/l4-single-destination-ip-port-bind-address.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden new file mode 100644 index 000000000000..d3657463fde9 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-ip-port-bind-address.golden @@ -0,0 +1,156 @@ +{ + "clusters": { + "null_route_cluster": { + "endpointGroup": { + "static": { + "config": { + "connectTimeout": "10s" + } + } + }, + "name": "null_route_cluster", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "tcp.api-1.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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": [ + { + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "1.1.1.1", + "port": 1234 + }, + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "routers": [ + { + "l4": { + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + } + ], + "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/destination/l4-single-destination-unix-socket-bind-address.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address.golden new file mode 100644 index 000000000000..19ca75501d5b --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-destination-unix-socket-bind-address.golden @@ -0,0 +1,93 @@ +{ + "clusters": { + "tcp.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "tcp.api-2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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": [ + { + "direction": "DIRECTION_OUTBOUND", + "name": "default/local/default/api-2:tcp:/path/to/socket", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-2.default.default.dc1" + } + } + ], + "unixSocket": { + "mode": "0666", + "path": "/path/to/socket" + } + } + ], + "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/destination/l4-single-implicit-destination-tproxy.golden b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy.golden new file mode 100644 index 000000000000..780d2a6f49a8 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/l4-single-implicit-destination-tproxy.golden @@ -0,0 +1,124 @@ +{ + "clusters": { + "original-destination": { + "endpointGroup": { + "passthrough": { + "config": { + "connectTimeout": "5s" + } + } + }, + "name": "original-destination", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "tcp.api-1.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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_TRANSPARENT" + ], + "defaultRouter": { + "l4": { + "cluster": { + "name": "original-destination" + }, + "statPrefix": "upstream.original-destination" + } + }, + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "127.0.0.1", + "port": 15001 + }, + "name": "outbound_listener", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-1.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-1.default.default.dc1" + }, + "match": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + } + ] + } + ], + "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/destination/mixed-multi-destination.golden b/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden new file mode 100644 index 000000000000..16b1841296ed --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/mixed-multi-destination.golden @@ -0,0 +1,380 @@ +{ + "clusters": { + "http.api-1.default.dc1.internal.foo.consul": { + "altStatName": "http.api-1.default.dc1.internal.foo.consul", + "failoverGroup": { + "config": { + "connectTimeout": "55s", + "useAltStatName": true + }, + "endpointGroups": [ + { + "dynamic": { + "config": { + "connectTimeout": "55s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~http" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + }, + "name": "failover-target~0~http.api-1.default.dc1.internal.foo.consul" + }, + { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~http" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "backup-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/backup1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + }, + "name": "failover-target~1~http.api-1.default.dc1.internal.foo.consul" + } + ] + }, + "name": "http.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" + }, + "http.api-2.default.dc1.internal.foo.consul": { + "altStatName": "http.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~http" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "http.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" + }, + "null_route_cluster": { + "endpointGroup": { + "static": { + "config": { + "connectTimeout": "10s" + } + } + }, + "name": "null_route_cluster", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-1.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-1.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-1.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api1-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "http.api-1.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "http.api-2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-1.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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": [ + { + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "1.1.1.1", + "port": 1234 + }, + "name": "default/local/default/api-1:tcp:1.1.1.1:1234", + "routers": [ + { + "l4": { + "statPrefix": "upstream.tcp.api-1.default.default.dc1", + "weightedClusters": { + "clusters": [ + { + "name": "tcp.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "tcp.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + } + } + ] + }, + { + "direction": "DIRECTION_OUTBOUND", + "name": "default/local/default/api-2:tcp:/path/to/socket", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-2.default.default.dc1" + } + } + ], + "unixSocket": { + "mode": "0666", + "path": "/path/to/socket" + } + }, + { + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "1.1.1.1", + "port": 1234 + }, + "name": "default/local/default/api-1:http:1.1.1.1:1234", + "routers": [ + { + "l7": { + "route": { + "name": "default/local/default/api-1:http:1.1.1.1:1234" + }, + "statPrefix": "upstream." + } + } + ] + } + ], + "routes": { + "default/local/default/api-1:http:1.1.1.1:1234": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "default/local/default/api-1:http:1.1.1.1:1234", + "routeRules": [ + { + "destination": { + "destinationConfiguration": { + "timeoutConfig": { + "timeout": "77s" + } + }, + "weightedClusters": { + "clusters": [ + { + "name": "http.api-2.default.dc1.internal.foo.consul", + "weight": 60 + }, + { + "name": "http.api-1.default.dc1.internal.foo.consul", + "weight": 40 + }, + { + "name": "null_route_cluster", + "weight": 10 + } + ] + } + }, + "match": { + "pathMatch": { + "prefix": "/split" + } + } + }, + { + "destination": { + "cluster": { + "name": "http.api-1.default.dc1.internal.foo.consul" + }, + "destinationConfiguration": { + "retryPolicy": { + "numRetries": 4, + "retryOn": "connect-failure" + }, + "timeoutConfig": { + "timeout": "606s" + } + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + }, + { + "destination": { + "cluster": { + "name": "null_route_cluster" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + } + }, + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + } +} 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 new file mode 100644 index 000000000000..7ac1ec80710b --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-multiple-implicit-destinations-tproxy.golden @@ -0,0 +1,466 @@ +{ + "clusters": { + "http.api-app.default.dc1.internal.foo.consul": { + "altStatName": "http.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~http" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "http.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_HTTP" + }, + "http.api-app2.default.dc1.internal.foo.consul": { + "altStatName": "http.api-app2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~http" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "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" + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp.api-app2.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app2.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-app2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.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", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app2.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app2-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-app2.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "http.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "http.api-app2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-app2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp2.api-app2.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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_TRANSPARENT" + ], + "defaultRouter": { + "l4": { + "cluster": { + "name": "original-destination" + }, + "statPrefix": "upstream.original-destination" + } + }, + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "127.0.0.1", + "port": 15001 + }, + "name": "outbound_listener", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l4": { + "cluster": { + "name": "tcp.api-app2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-app2.default.default.dc1" + }, + "match": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + } + }, + { + "l7": { + "route": { + "name": "default/local/default/api-app:http" + }, + "statPrefix": "upstream." + }, + "match": { + "destinationPort": 8080, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l7": { + "route": { + "name": "default/local/default/api-app2:http" + }, + "statPrefix": "upstream." + }, + "match": { + "destinationPort": 8080, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + } + }, + { + "l4": { + "cluster": { + "name": "tcp2.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l4": { + "cluster": { + "name": "tcp2.api-app2.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-app2.default.default.dc1" + }, + "match": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "2.2.2.2", + "prefixLen": 32 + }, + { + "addressPrefix": "3.3.3.3", + "prefixLen": 32 + } + ] + } + } + ] + } + ], + "routes": { + "default/local/default/api-app2:http": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "default/local/default/api-app2:http", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "http.api-app2.default.dc1.internal.foo.consul" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + }, + "default/local/default/api-app:http": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "default/local/default/api-app:http", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "http.api-app.default.dc1.internal.foo.consul" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + } + }, + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + } +} 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 new file mode 100644 index 000000000000..8f5e73c92ee5 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-tproxy.golden @@ -0,0 +1,262 @@ +{ + "clusters": { + "http.api-app.default.dc1.internal.foo.consul": { + "altStatName": "http.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~http" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "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" + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "http.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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_TRANSPARENT" + ], + "defaultRouter": { + "l4": { + "cluster": { + "name": "original-destination" + }, + "statPrefix": "upstream.original-destination" + } + }, + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "127.0.0.1", + "port": 15001 + }, + "name": "outbound_listener", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l7": { + "route": { + "name": "default/local/default/api-app:http" + }, + "statPrefix": "upstream." + }, + "match": { + "destinationPort": 8080, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l4": { + "cluster": { + "name": "tcp2.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + } + ] + } + ], + "routes": { + "default/local/default/api-app:http": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "default/local/default/api-app:http", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "http.api-app.default.dc1.internal.foo.consul" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + } + }, + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + } +} 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 new file mode 100644 index 000000000000..8f5e73c92ee5 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/destination/multiport-l4-and-l7-single-implicit-destination-with-multiple-workloads-tproxy.golden @@ -0,0 +1,262 @@ +{ + "clusters": { + "http.api-app.default.dc1.internal.foo.consul": { + "altStatName": "http.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~http" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "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" + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "altStatName": "tcp2.api-app.default.dc1.internal.foo.consul", + "endpointGroup": { + "dynamic": { + "config": { + "connectTimeout": "5s", + "disablePanicThreshold": true + }, + "outboundTls": { + "alpnProtocols": [ + "consul~tcp2" + ], + "outboundMesh": { + "identityKey": "test-identity", + "sni": "api-app.default.dc1.internal.foo.consul", + "validationContext": { + "spiffeIds": [ + "spiffe://foo.consul/ap/default/ns/default/identity/api-app-identity" + ], + "trustBundlePeerNameKey": "local" + } + } + } + } + }, + "name": "tcp2.api-app.default.dc1.internal.foo.consul", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "http.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + }, + "tcp2.api-app.default.dc1.internal.foo.consul": { + "endpoints": [ + { + "healthStatus": "HEALTH_STATUS_HEALTHY", + "hostPort": { + "host": "10.1.1.1", + "port": 20000 + } + } + ] + } + }, + "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_TRANSPARENT" + ], + "defaultRouter": { + "l4": { + "cluster": { + "name": "original-destination" + }, + "statPrefix": "upstream.original-destination" + } + }, + "direction": "DIRECTION_OUTBOUND", + "hostPort": { + "host": "127.0.0.1", + "port": 15001 + }, + "name": "outbound_listener", + "routers": [ + { + "l4": { + "cluster": { + "name": "tcp.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 7070, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l7": { + "route": { + "name": "default/local/default/api-app:http" + }, + "statPrefix": "upstream." + }, + "match": { + "destinationPort": 8080, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + }, + { + "l4": { + "cluster": { + "name": "tcp2.api-app.default.dc1.internal.foo.consul" + }, + "statPrefix": "upstream.tcp2.api-app.default.default.dc1" + }, + "match": { + "destinationPort": 8081, + "prefixRanges": [ + { + "addressPrefix": "1.1.1.1", + "prefixLen": 32 + } + ] + } + } + ] + } + ], + "routes": { + "default/local/default/api-app:http": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "default/local/default/api-app:http", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "http.api-app.default.dc1.internal.foo.consul" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + } + }, + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + } +} 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 000000000000..c88a05495613 --- /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 000000000000..439c536fdc3b --- /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 000000000000..439c536fdc3b --- /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/l7-expose-paths.golden b/internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths.golden new file mode 100644 index 000000000000..994b00f41514 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/l7-expose-paths.golden @@ -0,0 +1,213 @@ +{ + "clusters": { + "exposed_cluster_9090": { + "endpointGroup": { + "static": {} + }, + "name": "exposed_cluster_9090", + "protocol": "PROTOCOL_HTTP" + }, + "exposed_cluster_9091": { + "endpointGroup": { + "static": {} + }, + "name": "exposed_cluster_9091", + "protocol": "PROTOCOL_HTTP2" + }, + "local_app:port1": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "exposed_cluster_9090": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + }, + "exposed_cluster_9091": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9091 + } + } + ] + }, + "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" + ] + } + } + ] + }, + { + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 1234 + }, + "name": "exposed_path_health1234", + "routers": [ + { + "l7": { + "route": { + "name": "exposed_path_route_health1234" + }, + "statPrefix": "exposed_path_route_health1234", + "staticRoute": true + } + } + ] + }, + { + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 1235 + }, + "name": "exposed_path_GetHealth1235", + "routers": [ + { + "l7": { + "protocol": "L7_PROTOCOL_HTTP2", + "route": { + "name": "exposed_path_route_GetHealth1235" + }, + "statPrefix": "exposed_path_route_GetHealth1235", + "staticRoute": true + } + } + ] + } + ], + "routes": { + "exposed_path_route_GetHealth1235": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "exposed_path_route_GetHealth1235", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "exposed_cluster_9091" + } + }, + "match": { + "pathMatch": { + "exact": "GetHealth" + } + } + } + ] + } + ] + }, + "exposed_path_route_health1234": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "exposed_path_route_health1234", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "exposed_cluster_9090" + } + }, + "match": { + "pathMatch": { + "exact": "/health" + } + } + } + ] + } + ] + } + }, + "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/local-and-inbound-connections.golden b/internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections.golden new file mode 100644 index 000000000000..f75354038bf4 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/local-and-inbound-connections.golden @@ -0,0 +1,305 @@ +{ + "clusters": { + "exposed_cluster_9090": { + "endpointGroup": { + "static": {} + }, + "name": "exposed_cluster_9090", + "protocol": "PROTOCOL_HTTP" + }, + "exposed_cluster_9091": { + "endpointGroup": { + "static": {} + }, + "name": "exposed_cluster_9091", + "protocol": "PROTOCOL_HTTP2" + }, + "local_app:port1": { + "endpointGroup": { + "static": { + "config": { + "circuitBreakers": { + "upstreamLimits": { + "maxConnections": 123 + } + }, + "connectTimeout": "6s" + } + } + }, + "name": "local_app:port1", + "protocol": "PROTOCOL_TCP" + }, + "local_app:port3": { + "endpointGroup": { + "static": { + "config": { + "circuitBreakers": { + "upstreamLimits": { + "maxConnections": 123 + } + }, + "connectTimeout": "8s" + } + } + }, + "name": "local_app:port3", + "protocol": "PROTOCOL_HTTP" + } + }, + "endpoints": { + "exposed_cluster_9090": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + }, + "exposed_cluster_9091": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9091 + } + } + ] + }, + "local_app:port1": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + }, + "local_app:port3": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8081 + } + } + ] + } + }, + "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": [ + { + "balanceConnections": "BALANCE_CONNECTIONS_EXACT", + "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" + }, + "maxInboundConnections": "123", + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port1" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l7": { + "maxInboundConnections": "123", + "route": { + "name": "public_listener:port3" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~port3" + ] + } + } + ] + }, + { + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 1234 + }, + "name": "exposed_path_health1234", + "routers": [ + { + "l7": { + "route": { + "name": "exposed_path_route_health1234" + }, + "statPrefix": "exposed_path_route_health1234", + "staticRoute": true + } + } + ] + }, + { + "direction": "DIRECTION_INBOUND", + "hostPort": { + "host": "10.0.0.1", + "port": 1235 + }, + "name": "exposed_path_GetHealth1235", + "routers": [ + { + "l7": { + "protocol": "L7_PROTOCOL_HTTP2", + "route": { + "name": "exposed_path_route_GetHealth1235" + }, + "statPrefix": "exposed_path_route_GetHealth1235", + "staticRoute": true + } + } + ] + } + ], + "routes": { + "exposed_path_route_GetHealth1235": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "exposed_path_route_GetHealth1235", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "exposed_cluster_9091" + } + }, + "match": { + "pathMatch": { + "exact": "GetHealth" + } + } + } + ] + } + ] + }, + "exposed_path_route_health1234": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "exposed_path_route_health1234", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "exposed_cluster_9090" + } + }, + "match": { + "pathMatch": { + "exact": "/health" + } + } + } + ] + } + ] + }, + "public_listener:port3": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:port3", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:port3" + }, + "destinationConfiguration": { + "timeoutConfig": { + "timeout": "9s" + } + } + }, + "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/multiport-l4-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..e2798c8d4e49 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,131 @@ +{ + "clusters": { + "local_app:admin-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:admin-port", + "protocol": "PROTOCOL_TCP" + }, + "local_app:api-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:api-port", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "local_app:admin-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + }, + "local_app:api-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + } + }, + "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.3", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:admin-port" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~admin-port" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:api-port" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~api-port" + ] + } + } + ] + } + ], + "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/multiport-l4-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..21402c187b5e --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,131 @@ +{ + "clusters": { + "local_app:admin-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:admin-port", + "protocol": "PROTOCOL_TCP" + }, + "local_app:api-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:api-port", + "protocol": "PROTOCOL_TCP" + } + }, + "endpoints": { + "local_app:admin-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + }, + "local_app:api-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + } + }, + "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:admin-port" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~admin-port" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:api-port" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~api-port" + ] + } + } + ] + } + ], + "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/multiport-l4-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-single-workload-address-without-ports.golden new file mode 100644 index 000000000000..1487da213341 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-single-workload-address-without-ports.golden @@ -0,0 +1,129 @@ +{ + "clusters": { + "local_app:admin-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:admin-port" + }, + "local_app:api-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:api-port" + } + }, + "endpoints": { + "local_app:admin-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + }, + "local_app:api-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + } + }, + "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:admin-port" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~admin-port" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l4": { + "cluster": { + "name": "local_app:api-port" + }, + "statPrefix": "public_listener", + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~api-port" + ] + } + } + ] + } + ], + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + }, + "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" + } + } +} \ No newline at end of file diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port.golden new file mode 100644 index 000000000000..92f491e9e04d --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l4-workload-with-only-mesh-port.golden @@ -0,0 +1,62 @@ +{ + "clusters": { + "black-hole-cluster": { + "endpointGroup": { + "static": {} + }, + "name": "black-hole-cluster", + "protocol": "PROTOCOL_TCP" + } + }, + "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": [ + { + "l4": { + "cluster": { + "name": "black-hole-cluster" + }, + "statPrefix": "public_listener" + } + } + ] + } + ], + "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/multiport-l7-multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden new file mode 100644 index 000000000000..fdab88cd7c18 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-with-specific-ports.golden @@ -0,0 +1,184 @@ +{ + "clusters": { + "local_app:admin-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:admin-port", + "protocol": "PROTOCOL_HTTP" + }, + "local_app:api-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:api-port", + "protocol": "PROTOCOL_HTTP2" + } + }, + "endpoints": { + "local_app:admin-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + }, + "local_app:api-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + } + }, + "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.3", + "port": 20000 + }, + "name": "public_listener", + "routers": [ + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l7": { + "route": { + "name": "public_listener:admin-port" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~admin-port" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l7": { + "protocol": "L7_PROTOCOL_HTTP2", + "route": { + "name": "public_listener:api-port" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~api-port" + ] + } + } + ] + } + ], + "routes": { + "public_listener:admin-port": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:admin-port", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:admin-port" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + }, + "public_listener:api-port": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:api-port", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:api-port" + } + }, + "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/multiport-l7-multiple-workload-addresses-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden new file mode 100644 index 000000000000..3403eed7a864 --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-multiple-workload-addresses-without-ports.golden @@ -0,0 +1,251 @@ +{ + "clusters": { + "local_app:admin-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:admin-port", + "protocol": "PROTOCOL_HTTP" + }, + "local_app:api-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:api-port", + "protocol": "PROTOCOL_HTTP2" + }, + "local_app:grpc-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:grpc-port", + "protocol": "PROTOCOL_GRPC" + } + }, + "endpoints": { + "local_app:admin-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + }, + "local_app:api-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + }, + "local_app:grpc-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9091 + } + } + ] + } + }, + "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": { + "route": { + "name": "public_listener:admin-port" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~admin-port" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l7": { + "protocol": "L7_PROTOCOL_HTTP2", + "route": { + "name": "public_listener:api-port" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~api-port" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l7": { + "protocol": "L7_PROTOCOL_GRPC", + "route": { + "name": "public_listener:grpc-port" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~grpc-port" + ] + } + } + ] + } + ], + "routes": { + "public_listener:admin-port": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:admin-port", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:admin-port" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + }, + "public_listener:api-port": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:api-port", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:api-port" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + }, + "public_listener:grpc-port": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:grpc-port", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:grpc-port" + } + }, + "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/multiport-l7-single-workload-address-without-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-single-workload-address-without-ports.golden new file mode 100644 index 000000000000..460ede98100a --- /dev/null +++ b/internal/mesh/internal/controllers/xds/testdata/source/multiport-l7-single-workload-address-without-ports.golden @@ -0,0 +1,248 @@ +{ + "clusters": { + "local_app:admin-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:admin-port" + }, + "local_app:api-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:api-port" + }, + "local_app:grpc-port": { + "endpointGroup": { + "static": {} + }, + "name": "local_app:grpc-port" + } + }, + "endpoints": { + "local_app:admin-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 8080 + } + } + ] + }, + "local_app:api-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9090 + } + } + ] + }, + "local_app:grpc-port": { + "endpoints": [ + { + "hostPort": { + "host": "127.0.0.1", + "port": 9091 + } + } + ] + } + }, + "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": { + "route": { + "name": "public_listener:admin-port" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~admin-port" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l7": { + "protocol": "L7_PROTOCOL_HTTP2", + "route": { + "name": "public_listener:api-port" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~api-port" + ] + } + }, + { + "inboundTls": { + "inboundMesh": { + "identityKey": "test-identity", + "validationContext": { + "trustBundlePeerNameKeys": [ + "local" + ] + } + } + }, + "l7": { + "protocol": "L7_PROTOCOL_GRPC", + "route": { + "name": "public_listener:grpc-port" + }, + "statPrefix": "public_listener", + "staticRoute": true, + "trafficPermissions": {} + }, + "match": { + "alpnProtocols": [ + "consul~grpc-port" + ] + } + } + ] + } + ], + "routes": { + "public_listener:admin-port": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:admin-port", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:admin-port" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + }, + "public_listener:api-port": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:api-port", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:api-port" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + }, + "public_listener:grpc-port": { + "virtualHosts": [ + { + "domains": [ + "*" + ], + "name": "public_listener:grpc-port", + "routeRules": [ + { + "destination": { + "cluster": { + "name": "local_app:grpc-port" + } + }, + "match": { + "pathMatch": { + "prefix": "/" + } + } + } + ] + } + ] + } + }, + "trustBundles": { + "local": { + "roots": [ + "some-root", + "some-other-root" + ], + "trustDomain": "some-trust-domain" + } + }, + "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" + } + } +} \ No newline at end of file diff --git a/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper.go b/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper.go index 533474e6522a..7b064248414b 100644 --- a/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper.go +++ b/internal/mesh/internal/mappers/workloadselectionmapper/workload_selection_mapper.go @@ -6,29 +6,21 @@ package workloadselectionmapper import ( "context" - "google.golang.org/protobuf/proto" - + "github.com/hashicorp/consul/internal/catalog" "github.com/hashicorp/consul/internal/controller" "github.com/hashicorp/consul/internal/mesh/internal/mappers/common" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/mappers/selectiontracker" "github.com/hashicorp/consul/lib/stringslice" - pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" ) -// WorkloadSelecting denotes a resource type that uses workload selectors. -type WorkloadSelecting interface { - proto.Message - GetWorkloads() *pbcatalog.WorkloadSelector -} - -type Mapper[T WorkloadSelecting] struct { +type Mapper[T catalog.WorkloadSelecting] struct { workloadSelectionTracker *selectiontracker.WorkloadSelectionTracker computedType *pbresource.Type } -func New[T WorkloadSelecting](computedType *pbresource.Type) *Mapper[T] { +func New[T catalog.WorkloadSelecting](computedType *pbresource.Type) *Mapper[T] { if computedType == nil { panic("computed type is required") } diff --git a/internal/mesh/internal/types/destination_policy.go b/internal/mesh/internal/types/destination_policy.go index 75a6b9f18fb0..68b37345baf3 100644 --- a/internal/mesh/internal/types/destination_policy.go +++ b/internal/mesh/internal/types/destination_policy.go @@ -24,7 +24,7 @@ func RegisterDestinationPolicy(r resource.Registry) { ACLs: &resource.ACLHooks{ Read: aclReadHookDestinationPolicy, Write: aclWriteHookDestinationPolicy, - List: aclListHookDestinationPolicy, + List: resource.NoOpACLListHook, }, }) } @@ -233,9 +233,3 @@ func aclWriteHookDestinationPolicy(authorizer acl.Authorizer, authzContext *acl. // Check service:write permissions on the service this is controlling. return authorizer.ToAllowAuthorizer().ServiceWriteAllowed(serviceName, authzContext) } - -func aclListHookDestinationPolicy(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext) error { - // No-op List permission as we want to default to filtering resources - // from the list using the Read enforcement. - return nil -} diff --git a/internal/mesh/internal/types/destination_policy_test.go b/internal/mesh/internal/types/destination_policy_test.go index c2f89eeb0a9f..8edb51b2d831 100644 --- a/internal/mesh/internal/types/destination_policy_test.go +++ b/internal/mesh/internal/types/destination_policy_test.go @@ -4,13 +4,13 @@ package types import ( + "fmt" "testing" "time" "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/durationpb" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/resourcetest" @@ -518,99 +518,92 @@ func TestDestinationPolicyACLs(t *testing.T) { registry := resource.NewRegistry() Register(registry) - type testcase struct { - rules string - check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource) - readOK string - writeOK string - listOK string + newPolicy := func(t *testing.T, tenancyStr string) *pbresource.Resource { + res := resourcetest.Resource(pbmesh.DestinationPolicyType, "api"). + WithTenancy(resourcetest.Tenancy(tenancyStr)). + WithData(t, &pbmesh.DestinationPolicy{ + PortConfigs: map[string]*pbmesh.DestinationConfig{ + "http": { + ConnectTimeout: durationpb.New(55 * time.Second), + }, + }, + }). + Build() + resourcetest.ValidateAndNormalize(t, registry, res) + return res } const ( - DENY = "deny" - ALLOW = "allow" - DEFAULT = "default" + DENY = resourcetest.DENY + ALLOW = resourcetest.ALLOW + DEFAULT = resourcetest.DEFAULT ) - checkF := func(t *testing.T, expect string, got error) { - switch expect { - case ALLOW: - if acl.IsErrPermissionDenied(got) { - t.Fatal("should be allowed") - } - case DENY: - if !acl.IsErrPermissionDenied(got) { - t.Fatal("should be denied") - } - case DEFAULT: - require.Nil(t, got, "expected fallthrough decision") - default: - t.Fatalf("unexpected expectation: %q", expect) - } + run := func(t *testing.T, name string, tc resourcetest.ACLTestCase) { + t.Run(name, func(t *testing.T) { + resourcetest.RunACLTestCase(t, tc, registry) + }) } - reg, ok := registry.Resolve(pbmesh.DestinationPolicyType) - require.True(t, ok) + isEnterprise := (structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default") - run := func(t *testing.T, tc testcase) { - destData := &pbmesh.DestinationPolicy{ - PortConfigs: map[string]*pbmesh.DestinationConfig{ - "http": { - ConnectTimeout: durationpb.New(55 * time.Second), - }, - }, + serviceRead := func(partition, namespace, name string) string { + if isEnterprise { + return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "read" } } }`, partition, namespace, name) } - res := resourcetest.Resource(pbmesh.DestinationPolicyType, "api"). - WithTenancy(resource.DefaultNamespacedTenancy()). - WithData(t, destData). - Build() - resourcetest.ValidateAndNormalize(t, registry, res) - - config := acl.Config{ - WildcardName: structs.WildcardSpecifier, + return fmt.Sprintf(` service %q { policy = "read" } `, name) + } + serviceWrite := func(partition, namespace, name string) string { + if isEnterprise { + return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "write" } } }`, partition, namespace, name) } - authz, err := acl.NewAuthorizerFromRules(tc.rules, &config, nil) - require.NoError(t, err) - authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) + return fmt.Sprintf(` service %q { policy = "write" } `, name) + } - t.Run("read", func(t *testing.T) { - err := reg.ACLs.Read(authz, &acl.AuthorizerContext{}, res.Id, nil) - checkF(t, tc.readOK, err) - }) - t.Run("write", func(t *testing.T) { - err := reg.ACLs.Write(authz, &acl.AuthorizerContext{}, res) - checkF(t, tc.writeOK, err) - }) - t.Run("list", func(t *testing.T) { - err := reg.ACLs.List(authz, &acl.AuthorizerContext{}) - checkF(t, tc.listOK, err) - }) + assert := func(t *testing.T, name string, rules string, res *pbresource.Resource, readOK, writeOK string) { + tc := resourcetest.ACLTestCase{ + AuthCtx: resource.AuthorizerContext(res.Id.Tenancy), + Rules: rules, + Res: res, + ReadOK: readOK, + WriteOK: writeOK, + ListOK: DEFAULT, + } + run(t, name, tc) } - cases := map[string]testcase{ - "no rules": { - rules: ``, - readOK: DENY, - writeOK: DENY, - listOK: DEFAULT, - }, - "service api read": { - rules: `service "api" { policy = "read" }`, - readOK: ALLOW, - writeOK: DENY, - listOK: DEFAULT, - }, - "service api write": { - rules: `service "api" { policy = "write" }`, - readOK: ALLOW, - writeOK: ALLOW, - listOK: DEFAULT, - }, + tenancies := []string{"default.default"} + if isEnterprise { + tenancies = append(tenancies, "default.foo", "alpha.default", "alpha.foo") } - for name, tc := range cases { - t.Run(name, func(t *testing.T) { - run(t, tc) + for _, policyTenancyStr := range tenancies { + t.Run("policy tenancy: "+policyTenancyStr, func(t *testing.T) { + for _, aclTenancyStr := range tenancies { + t.Run("acl tenancy: "+aclTenancyStr, func(t *testing.T) { + aclTenancy := resourcetest.Tenancy(aclTenancyStr) + + maybe := func(match string) string { + if policyTenancyStr != aclTenancyStr { + return DENY + } + return match + } + + t.Run("no rules", func(t *testing.T) { + rules := `` + assert(t, "any", rules, newPolicy(t, policyTenancyStr), DENY, DENY) + }) + t.Run("api:read", func(t *testing.T) { + rules := serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "api") + assert(t, "any", rules, newPolicy(t, policyTenancyStr), maybe(ALLOW), DENY) + }) + t.Run("api:write", func(t *testing.T) { + rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api") + assert(t, "any", rules, newPolicy(t, policyTenancyStr), maybe(ALLOW), maybe(ALLOW)) + }) + }) + } }) } } diff --git a/internal/mesh/internal/types/destinations.go b/internal/mesh/internal/types/destinations.go index 657aa33cb0a0..34287e627ab7 100644 --- a/internal/mesh/internal/types/destinations.go +++ b/internal/mesh/internal/types/destinations.go @@ -4,6 +4,8 @@ package types import ( + "net" + "github.com/hashicorp/go-multierror" "google.golang.org/protobuf/proto" @@ -20,6 +22,7 @@ func RegisterDestinations(r resource.Registry) { Scope: resource.ScopeNamespace, Mutate: MutateDestinations, Validate: ValidateDestinations, + ACLs: catalog.ACLHooksForWorkloadSelectingType[*pbmesh.Destinations](), }) } @@ -73,7 +76,6 @@ func ValidateDestinations(res *pbresource.Resource) error { var merr error - // Validate the workload selector if selErr := catalog.ValidateSelector(destinations.Workloads, false); selErr != nil { merr = multierror.Append(merr, resource.ErrInvalidField{ Name: "workloads", @@ -81,10 +83,17 @@ func ValidateDestinations(res *pbresource.Resource) error { }) } + if destinations.GetPqDestinations() != nil { + merr = multierror.Append(merr, resource.ErrInvalidField{ + Name: "pq_destinations", + Wrapped: resource.ErrUnsupported, + }) + } + for i, dest := range destinations.Destinations { wrapDestErr := func(err error) error { return resource.ErrInvalidListElement{ - Name: "upstreams", + Name: "destinations", Index: i, Wrapped: err, } @@ -101,8 +110,73 @@ func ValidateDestinations(res *pbresource.Resource) error { merr = multierror.Append(merr, refErr) } - // TODO(v2): validate port name using catalog validator - // TODO(v2): validate ListenAddr + if portErr := catalog.ValidatePortName(dest.DestinationPort); portErr != nil { + merr = multierror.Append(merr, wrapDestErr(resource.ErrInvalidField{ + Name: "destination_port", + Wrapped: portErr, + })) + } + + if dest.GetDatacenter() != "" { + merr = multierror.Append(merr, wrapDestErr(resource.ErrInvalidField{ + Name: "datacenter", + Wrapped: resource.ErrUnsupported, + })) + } + + if listenAddrErr := validateListenAddr(dest); listenAddrErr != nil { + merr = multierror.Append(merr, wrapDestErr(listenAddrErr)) + } + } + + return merr +} + +func validateListenAddr(dest *pbmesh.Destination) error { + var merr error + + if dest.GetListenAddr() == nil { + return multierror.Append(merr, resource.ErrInvalidFields{ + Names: []string{"ip_port", "unix"}, + Wrapped: resource.ErrMissingOneOf, + }) + } + + switch listenAddr := dest.GetListenAddr().(type) { + case *pbmesh.Destination_IpPort: + if ipPortErr := validateIPPort(listenAddr.IpPort); ipPortErr != nil { + merr = multierror.Append(merr, resource.ErrInvalidField{ + Name: "ip_port", + Wrapped: ipPortErr, + }) + } + case *pbmesh.Destination_Unix: + if !catalog.IsValidUnixSocketPath(listenAddr.Unix.GetPath()) { + merr = multierror.Append(merr, resource.ErrInvalidField{ + Name: "unix", + Wrapped: resource.ErrInvalidField{ + Name: "path", + Wrapped: errInvalidUnixSocketPath, + }, + }) + } + } + + return merr +} + +func validateIPPort(ipPort *pbmesh.IPPortAddress) error { + var merr error + + if listenPortErr := validatePort(ipPort.GetPort(), "port"); listenPortErr != nil { + merr = multierror.Append(merr, listenPortErr) + } + + if net.ParseIP(ipPort.GetIp()) == nil { + merr = multierror.Append(merr, resource.ErrInvalidField{ + Name: "ip", + Wrapped: errInvalidIP, + }) } return merr diff --git a/internal/mesh/internal/types/destinations_configuration.go b/internal/mesh/internal/types/destinations_configuration.go index b5de19d029b5..fedbe40df48c 100644 --- a/internal/mesh/internal/types/destinations_configuration.go +++ b/internal/mesh/internal/types/destinations_configuration.go @@ -7,17 +7,19 @@ import ( "github.com/hashicorp/go-multierror" "github.com/hashicorp/consul/internal/catalog" + "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" ) -func RegisterUpstreamsConfiguration(r resource.Registry) { +func RegisterDestinationsConfiguration(r resource.Registry) { r.Register(resource.Registration{ Type: pbmesh.DestinationsConfigurationType, Proto: &pbmesh.DestinationsConfiguration{}, Scope: resource.ScopeNamespace, Validate: ValidateDestinationsConfiguration, + ACLs: catalog.ACLHooksForWorkloadSelectingType[*pbmesh.DestinationsConfiguration](), }) } diff --git a/internal/mesh/internal/types/destinations_configuration_test.go b/internal/mesh/internal/types/destinations_configuration_test.go index 29c7c7cae0f1..11af0732d5d9 100644 --- a/internal/mesh/internal/types/destinations_configuration_test.go +++ b/internal/mesh/internal/types/destinations_configuration_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" + catalogtesthelpers "github.com/hashicorp/consul/internal/catalog/catalogtest/helpers" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/resourcetest" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" @@ -16,6 +17,15 @@ import ( "github.com/hashicorp/consul/sdk/testutil" ) +func TestDestinationsConfigurationACLs(t *testing.T) { + catalogtesthelpers.RunWorkloadSelectingTypeACLsTests[*pbmesh.DestinationsConfiguration](t, pbmesh.DestinationsConfigurationType, + func(selector *pbcatalog.WorkloadSelector) *pbmesh.DestinationsConfiguration { + return &pbmesh.DestinationsConfiguration{Workloads: selector} + }, + RegisterDestinationsConfiguration, + ) +} + func TestValidateDestinationsConfiguration(t *testing.T) { type testcase struct { data *pbmesh.DestinationsConfiguration diff --git a/internal/mesh/internal/types/destinations_test.go b/internal/mesh/internal/types/destinations_test.go index 2601e884df07..55624a6316f4 100644 --- a/internal/mesh/internal/types/destinations_test.go +++ b/internal/mesh/internal/types/destinations_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/require" + catalogtesthelpers "github.com/hashicorp/consul/internal/catalog/catalogtest/helpers" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/resourcetest" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" @@ -17,7 +18,7 @@ import ( "github.com/hashicorp/consul/sdk/testutil" ) -func TestMutateUpstreams(t *testing.T) { +func TestMutateDestinations(t *testing.T) { type testcase struct { tenancy *pbresource.Tenancy data *pbmesh.Destinations @@ -86,7 +87,7 @@ func TestMutateUpstreams(t *testing.T) { } } -func TestValidateUpstreams(t *testing.T) { +func TestValidateDestinations(t *testing.T) { type testcase struct { data *pbmesh.Destinations skipMutate bool @@ -151,7 +152,7 @@ func TestValidateUpstreams(t *testing.T) { {DestinationRef: nil}, }, }, - expectErr: `invalid element at index 0 of list "upstreams": invalid "destination_ref" field: missing required field`, + expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: missing required field`, }, "dest/bad type": { skipMutate: true, @@ -163,7 +164,7 @@ func TestValidateUpstreams(t *testing.T) { {DestinationRef: newRefWithTenancy(pbcatalog.WorkloadType, "default.default", "api")}, }, }, - expectErr: `invalid element at index 0 of list "upstreams": invalid "destination_ref" field: invalid "type" field: reference must have type catalog.v2beta1.Service`, + expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "type" field: reference must have type catalog.v2beta1.Service`, }, "dest/nil tenancy": { skipMutate: true, @@ -175,7 +176,7 @@ func TestValidateUpstreams(t *testing.T) { {DestinationRef: &pbresource.Reference{Type: pbcatalog.ServiceType, Name: "api"}}, }, }, - expectErr: `invalid element at index 0 of list "upstreams": invalid "destination_ref" field: invalid "tenancy" field: missing required field`, + expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "tenancy" field: missing required field`, }, "dest/bad dest tenancy/partition": { skipMutate: true, @@ -187,7 +188,7 @@ func TestValidateUpstreams(t *testing.T) { {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, ".bar", "api")}, }, }, - expectErr: `invalid element at index 0 of list "upstreams": invalid "destination_ref" field: invalid "tenancy" field: invalid "partition" field: cannot be empty`, + expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "tenancy" field: invalid "partition" field: cannot be empty`, }, "dest/bad dest tenancy/namespace": { skipMutate: true, @@ -199,7 +200,7 @@ func TestValidateUpstreams(t *testing.T) { {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo", "api")}, }, }, - expectErr: `invalid element at index 0 of list "upstreams": invalid "destination_ref" field: invalid "tenancy" field: invalid "namespace" field: cannot be empty`, + expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "tenancy" field: invalid "namespace" field: cannot be empty`, }, "dest/bad dest tenancy/peer_name": { skipMutate: true, @@ -213,17 +214,158 @@ func TestValidateUpstreams(t *testing.T) { Reference("")}, }, }, - expectErr: `invalid element at index 0 of list "upstreams": invalid "destination_ref" field: invalid "tenancy" field: invalid "peer_name" field: must be set to "local"`, + expectErr: `invalid element at index 0 of list "destinations": invalid "destination_ref" field: invalid "tenancy" field: invalid "peer_name" field: must be set to "local"`, }, - "normal": { + "unsupported pq_destinations": { + skipMutate: true, data: &pbmesh.Destinations{ - Workloads: &pbcatalog.WorkloadSelector{ - Names: []string{"blah"}, + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + PqDestinations: []*pbmesh.PreparedQueryDestination{ + {Name: "foo-query"}, }, + }, + expectErr: `invalid "pq_destinations" field: field is currently not supported`, + }, + "missing destination port": { + skipMutate: true, + data: &pbmesh.Destinations{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, Destinations: []*pbmesh.Destination{ - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api")}, - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.zim", "api")}, - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api")}, + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: "127.0.0.1", + Port: 1234, + }, + }, + }, + }, + }, + expectErr: `invalid element at index 0 of list "destinations": invalid "destination_port" field: cannot be empty`, + }, + "unsupported datacenter": { + skipMutate: true, + data: &pbmesh.Destinations{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + Destinations: []*pbmesh.Destination{ + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), + DestinationPort: "p1", + Datacenter: "dc2", + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: "127.0.0.1", + Port: 1234, + }, + }, + }, + }, + }, + expectErr: `invalid element at index 0 of list "destinations": invalid "datacenter" field: field is currently not supported`, + }, + "missing listen addr": { + skipMutate: true, + data: &pbmesh.Destinations{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + Destinations: []*pbmesh.Destination{ + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), + DestinationPort: "p1", + }, + }, + }, + expectErr: `invalid "ip_port,unix" fields: missing one of the required fields`, + }, + "invalid ip for listen addr": { + skipMutate: true, + data: &pbmesh.Destinations{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + Destinations: []*pbmesh.Destination{ + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), + DestinationPort: "p1", + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: "invalid", + Port: 1234, + }, + }, + }, + }, + }, + expectErr: `invalid "ip" field: IP address is not valid`, + }, + "invalid port for listen addr": { + skipMutate: true, + data: &pbmesh.Destinations{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + Destinations: []*pbmesh.Destination{ + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), + DestinationPort: "p1", + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: "127.0.0.1", + Port: 0, + }, + }, + }, + }, + }, + expectErr: `invalid "port" field: port number is outside the range 1 to 65535`, + }, + "invalid unix path for listen addr": { + skipMutate: true, + data: &pbmesh.Destinations{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + Destinations: []*pbmesh.Destination{ + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), + DestinationPort: "p1", + ListenAddr: &pbmesh.Destination_Unix{ + Unix: &pbmesh.UnixSocketAddress{ + Path: "foo", + }, + }, + }, + }, + }, + expectErr: `invalid "unix" field: invalid "path" field: unix socket path is not valid`, + }, + "normal": { + data: &pbmesh.Destinations{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + Destinations: []*pbmesh.Destination{ + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), + DestinationPort: "p1", + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: "127.0.0.1", + Port: 1234, + }, + }, + }, + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.zim", "api"), + DestinationPort: "p2", + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: "127.0.0.1", + Port: 1235, + }, + }, + }, + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api"), + DestinationPort: "p3", + ListenAddr: &pbmesh.Destination_Unix{ + Unix: &pbmesh.UnixSocketAddress{ + Path: "unix://foo/bar", + }, + }, + }, }, }, }, @@ -234,9 +376,35 @@ func TestValidateUpstreams(t *testing.T) { Filter: "metadata.foo == bar", }, Destinations: []*pbmesh.Destination{ - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api")}, - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.zim", "api")}, - {DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api")}, + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.bar", "api"), + DestinationPort: "p1", + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: "127.0.0.1", + Port: 1234, + }, + }, + }, + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "foo.zim", "api"), + DestinationPort: "p2", + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: "127.0.0.1", + Port: 1235, + }, + }, + }, + { + DestinationRef: newRefWithTenancy(pbcatalog.ServiceType, "gir.zim", "api"), + DestinationPort: "p3", + ListenAddr: &pbmesh.Destination_Unix{ + Unix: &pbmesh.UnixSocketAddress{ + Path: "unix://foo/bar", + }, + }, + }, }, }, }, @@ -248,3 +416,12 @@ func TestValidateUpstreams(t *testing.T) { }) } } + +func TestDestinationsACLs(t *testing.T) { + catalogtesthelpers.RunWorkloadSelectingTypeACLsTests[*pbmesh.Destinations](t, pbmesh.DestinationsType, + func(selector *pbcatalog.WorkloadSelector) *pbmesh.Destinations { + return &pbmesh.Destinations{Workloads: selector} + }, + RegisterDestinations, + ) +} diff --git a/internal/mesh/internal/types/errors.go b/internal/mesh/internal/types/errors.go new file mode 100644 index 000000000000..bc9dacbbf0c4 --- /dev/null +++ b/internal/mesh/internal/types/errors.go @@ -0,0 +1,16 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package types + +import ( + "errors" +) + +var ( + errInvalidPort = errors.New("port number is outside the range 1 to 65535") + errInvalidIP = errors.New("IP address is not valid") + errInvalidUnixSocketPath = errors.New("unix socket path is not valid") + errInvalidExposePathProtocol = errors.New("invalid protocol: only HTTP and HTTP2 protocols are allowed") + errMissingProxyConfigData = errors.New("at least one of \"bootstrap_config\" or \"dynamic_config\" fields must be set") +) diff --git a/internal/mesh/internal/types/proxy_configuration.go b/internal/mesh/internal/types/proxy_configuration.go index 590ee27aeb1b..081324d72167 100644 --- a/internal/mesh/internal/types/proxy_configuration.go +++ b/internal/mesh/internal/types/proxy_configuration.go @@ -4,9 +4,12 @@ package types import ( - "github.com/hashicorp/go-multierror" + "math" "github.com/hashicorp/consul/internal/catalog" + + "github.com/hashicorp/go-multierror" + "github.com/hashicorp/consul/internal/resource" pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" "github.com/hashicorp/consul/proto-public/pbresource" @@ -20,6 +23,7 @@ func RegisterProxyConfiguration(r resource.Registry) { Scope: resource.ScopeNamespace, Mutate: MutateProxyConfiguration, Validate: ValidateProxyConfiguration, + ACLs: catalog.ACLHooksForWorkloadSelectingType[*pbmesh.ProxyConfiguration](), }) } @@ -53,23 +57,174 @@ func MutateProxyConfiguration(res *pbresource.Resource) error { } func ValidateProxyConfiguration(res *pbresource.Resource) error { - var cfg pbmesh.ProxyConfiguration - - if err := res.Data.UnmarshalTo(&cfg); err != nil { - return resource.NewErrDataParse(&cfg, err) + decodedProxyCfg, decodeErr := resource.Decode[*pbmesh.ProxyConfiguration](res) + if decodeErr != nil { + return resource.NewErrDataParse(decodedProxyCfg.GetData(), decodeErr) } + proxyCfg := decodedProxyCfg.GetData() - var merr error + var err error - // Validate the workload selector - if selErr := catalog.ValidateSelector(cfg.Workloads, false); selErr != nil { - merr = multierror.Append(merr, resource.ErrInvalidField{ + if selErr := catalog.ValidateSelector(proxyCfg.Workloads, false); selErr != nil { + err = multierror.Append(err, resource.ErrInvalidField{ Name: "workloads", Wrapped: selErr, }) } - // TODO(rb): add more validation for proxy configuration + if proxyCfg.GetDynamicConfig() == nil && proxyCfg.GetBootstrapConfig() == nil { + err = multierror.Append(err, resource.ErrInvalidFields{ + Names: []string{"dynamic_config", "bootstrap_config"}, + Wrapped: errMissingProxyConfigData, + }) + } + + // nolint:staticcheck + if proxyCfg.GetOpaqueConfig() != nil { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "opaque_config", + Wrapped: resource.ErrUnsupported, + }) + } + + if dynamicCfgErr := validateDynamicProxyConfiguration(proxyCfg.GetDynamicConfig()); dynamicCfgErr != nil { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "dynamic_config", + Wrapped: dynamicCfgErr, + }) + } + + return err +} + +func validateDynamicProxyConfiguration(cfg *pbmesh.DynamicConfig) error { + if cfg == nil { + return nil + } + + var err error + + // Error if any of the currently unsupported fields is set. + if cfg.GetMutualTlsMode() != pbmesh.MutualTLSMode_MUTUAL_TLS_MODE_DEFAULT { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "mutual_tls_mode", + Wrapped: resource.ErrUnsupported, + }) + } + + if cfg.GetMeshGatewayMode() != pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "mesh_gateway_mode", + Wrapped: resource.ErrUnsupported, + }) + } + + if cfg.GetAccessLogs() != nil { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "access_logs", + Wrapped: resource.ErrUnsupported, + }) + } + + if cfg.GetPublicListenerJson() != "" { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "public_listener_json", + Wrapped: resource.ErrUnsupported, + }) + } - return merr + if cfg.GetListenerTracingJson() != "" { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "listener_tracing_json", + Wrapped: resource.ErrUnsupported, + }) + } + + if cfg.GetLocalClusterJson() != "" { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "local_cluster_json", + Wrapped: resource.ErrUnsupported, + }) + } + + // nolint:staticcheck + if cfg.GetLocalWorkloadAddress() != "" { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "local_workload_address", + Wrapped: resource.ErrUnsupported, + }) + } + + // nolint:staticcheck + if cfg.GetLocalWorkloadPort() != 0 { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "local_workload_port", + Wrapped: resource.ErrUnsupported, + }) + } + + // nolint:staticcheck + if cfg.GetLocalWorkloadSocketPath() != "" { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "local_workload_socket_path", + Wrapped: resource.ErrUnsupported, + }) + } + + if tproxyCfg := cfg.GetTransparentProxy(); tproxyCfg != nil { + if tproxyCfg.DialedDirectly { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "transparent_proxy", + Wrapped: resource.ErrInvalidField{ + Name: "dialed_directly", + Wrapped: resource.ErrUnsupported, + }, + }) + } + + if outboundListenerPortErr := validatePort(tproxyCfg.OutboundListenerPort, "outbound_listener_port"); outboundListenerPortErr != nil { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "transparent_proxy", + Wrapped: outboundListenerPortErr, + }) + } + } + + if exposeCfg := cfg.GetExposeConfig(); exposeCfg != nil { + for i, path := range exposeCfg.GetExposePaths() { + if listenerPortErr := validatePort(path.ListenerPort, "listener_port"); listenerPortErr != nil { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "expose_config", + Wrapped: resource.ErrInvalidListElement{ + Name: "expose_paths", + Index: i, + Wrapped: listenerPortErr, + }, + }) + } + + if localPathPortErr := validatePort(path.LocalPathPort, "local_path_port"); localPathPortErr != nil { + err = multierror.Append(err, resource.ErrInvalidField{ + Name: "expose_config", + Wrapped: resource.ErrInvalidListElement{ + Name: "expose_paths", + Index: i, + Wrapped: localPathPortErr, + }, + }) + } + } + } + + return err +} + +func validatePort(port uint32, fieldName string) error { + if port < 1 || port > math.MaxUint16 { + return resource.ErrInvalidField{ + Name: fieldName, + Wrapped: errInvalidPort, + } + } + return nil } diff --git a/internal/mesh/internal/types/proxy_configuration_test.go b/internal/mesh/internal/types/proxy_configuration_test.go index 44d8b8820af4..f5c52d474c35 100644 --- a/internal/mesh/internal/types/proxy_configuration_test.go +++ b/internal/mesh/internal/types/proxy_configuration_test.go @@ -4,10 +4,14 @@ package types import ( + "math" "testing" + "github.com/hashicorp/go-multierror" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/types/known/structpb" + catalogtesthelpers "github.com/hashicorp/consul/internal/catalog/catalogtest/helpers" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/resourcetest" pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" @@ -17,6 +21,18 @@ import ( "github.com/hashicorp/consul/sdk/testutil" ) +func TestProxyConfigurationACLs(t *testing.T) { + catalogtesthelpers.RunWorkloadSelectingTypeACLsTests[*pbmesh.ProxyConfiguration](t, pbmesh.ProxyConfigurationType, + func(selector *pbcatalog.WorkloadSelector) *pbmesh.ProxyConfiguration { + return &pbmesh.ProxyConfiguration{ + Workloads: selector, + DynamicConfig: &pbmesh.DynamicConfig{}, + } + }, + RegisterProxyConfiguration, + ) +} + func TestMutateProxyConfiguration(t *testing.T) { cases := map[string]struct { data *pbmesh.ProxyConfiguration @@ -86,7 +102,194 @@ func TestMutateProxyConfiguration(t *testing.T) { } } -func TestValidateProxyConfiguration(t *testing.T) { +func TestValidateProxyConfiguration_MissingBothDynamicAndBootstrapConfig(t *testing.T) { + proxyCfg := &pbmesh.ProxyConfiguration{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + } + + res := resourcetest.Resource(pbmesh.ProxyConfigurationType, "test"). + WithData(t, proxyCfg). + Build() + + err := ValidateProxyConfiguration(res) + + var expError error + expError = multierror.Append(expError, + resource.ErrInvalidFields{ + Names: []string{"dynamic_config", "bootstrap_config"}, + Wrapped: errMissingProxyConfigData, + }, + ) + require.Equal(t, err, expError) +} + +func TestValidateProxyConfiguration_AllFieldsInvalid(t *testing.T) { + proxyCfg := &pbmesh.ProxyConfiguration{ + // Omit workload selector. + + DynamicConfig: &pbmesh.DynamicConfig{ + // Set unsupported fields. + MutualTlsMode: pbmesh.MutualTLSMode_MUTUAL_TLS_MODE_PERMISSIVE, + MeshGatewayMode: pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_LOCAL, + AccessLogs: &pbmesh.AccessLogsConfig{}, + PublicListenerJson: "listener-json", + ListenerTracingJson: "tracing-json", + LocalClusterJson: "cluster-json", + LocalWorkloadAddress: "1.1.1.1", + LocalWorkloadPort: 1234, + LocalWorkloadSocketPath: "/foo/bar", + + TransparentProxy: &pbmesh.TransparentProxy{ + DialedDirectly: true, // unsupported + OutboundListenerPort: math.MaxUint16 + 1, // invalid + }, + + // Create invalid expose paths config. + ExposeConfig: &pbmesh.ExposeConfig{ + ExposePaths: []*pbmesh.ExposePath{ + { + ListenerPort: 0, + LocalPathPort: math.MaxUint16 + 1, + }, + }, + }, + }, + + OpaqueConfig: &structpb.Struct{}, + } + + res := resourcetest.Resource(pbmesh.ProxyConfigurationType, "test"). + WithData(t, proxyCfg). + Build() + + err := ValidateProxyConfiguration(res) + + var dynamicCfgErr error + unsupportedFields := []string{ + "mutual_tls_mode", + "mesh_gateway_mode", + "access_logs", + "public_listener_json", + "listener_tracing_json", + "local_cluster_json", + "local_workload_address", + "local_workload_port", + "local_workload_socket_path", + } + for _, f := range unsupportedFields { + dynamicCfgErr = multierror.Append(dynamicCfgErr, + resource.ErrInvalidField{ + Name: f, + Wrapped: resource.ErrUnsupported, + }, + ) + } + dynamicCfgErr = multierror.Append(dynamicCfgErr, + resource.ErrInvalidField{ + Name: "transparent_proxy", + Wrapped: resource.ErrInvalidField{ + Name: "dialed_directly", + Wrapped: resource.ErrUnsupported, + }, + }, + resource.ErrInvalidField{ + Name: "transparent_proxy", + Wrapped: resource.ErrInvalidField{ + Name: "outbound_listener_port", + Wrapped: errInvalidPort, + }, + }, + resource.ErrInvalidField{ + Name: "expose_config", + Wrapped: resource.ErrInvalidListElement{ + Name: "expose_paths", + Wrapped: resource.ErrInvalidField{ + Name: "listener_port", + Wrapped: errInvalidPort, + }, + }, + }, + resource.ErrInvalidField{ + Name: "expose_config", + Wrapped: resource.ErrInvalidListElement{ + Name: "expose_paths", + Wrapped: resource.ErrInvalidField{ + Name: "local_path_port", + Wrapped: errInvalidPort, + }, + }, + }, + ) + + var expError error + expError = multierror.Append(expError, + resource.ErrInvalidField{ + Name: "workloads", + Wrapped: resource.ErrEmpty, + }, + resource.ErrInvalidField{ + Name: "opaque_config", + Wrapped: resource.ErrUnsupported, + }, + resource.ErrInvalidField{ + Name: "dynamic_config", + Wrapped: dynamicCfgErr, + }, + ) + + require.Equal(t, err, expError) +} + +func TestValidateProxyConfiguration_AllFieldsValid(t *testing.T) { + proxyCfg := &pbmesh.ProxyConfiguration{ + Workloads: &pbcatalog.WorkloadSelector{Names: []string{"foo"}}, + + DynamicConfig: &pbmesh.DynamicConfig{ + MutualTlsMode: pbmesh.MutualTLSMode_MUTUAL_TLS_MODE_DEFAULT, + MeshGatewayMode: pbmesh.MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED, + + TransparentProxy: &pbmesh.TransparentProxy{ + DialedDirectly: false, + OutboundListenerPort: 15500, + }, + + ExposeConfig: &pbmesh.ExposeConfig{ + ExposePaths: []*pbmesh.ExposePath{ + { + ListenerPort: 1234, + LocalPathPort: 1235, + }, + }, + }, + }, + + BootstrapConfig: &pbmesh.BootstrapConfig{ + StatsdUrl: "stats-url", + DogstatsdUrl: "dogstats-url", + StatsTags: []string{"tags"}, + PrometheusBindAddr: "prom-bind-addr", + StatsBindAddr: "stats-bind-addr", + ReadyBindAddr: "ready-bind-addr", + OverrideJsonTpl: "override-json-tpl", + StaticClustersJson: "static-clusters-json", + StaticListenersJson: "static-listeners-json", + StatsSinksJson: "stats-sinks-json", + StatsConfigJson: "stats-config-json", + StatsFlushInterval: "stats-flush-interval", + TracingConfigJson: "tracing-config-json", + TelemetryCollectorBindSocketDir: "telemetry-collector-bind-socket-dir", + }, + } + + res := resourcetest.Resource(pbmesh.ProxyConfigurationType, "test"). + WithData(t, proxyCfg). + Build() + + err := ValidateProxyConfiguration(res) + require.NoError(t, err) +} + +func TestValidateProxyConfiguration_WorkloadSelector(t *testing.T) { type testcase struct { data *pbmesh.ProxyConfiguration expectErr string @@ -146,6 +349,7 @@ func TestValidateProxyConfiguration(t *testing.T) { Names: []string{"blah"}, Filter: "metadata.foo == bar", }, + DynamicConfig: &pbmesh.DynamicConfig{}, }, }, } diff --git a/internal/mesh/internal/types/proxy_state_template.go b/internal/mesh/internal/types/proxy_state_template.go index 010d0f9591b3..7db3dbaf55fd 100644 --- a/internal/mesh/internal/types/proxy_state_template.go +++ b/internal/mesh/internal/types/proxy_state_template.go @@ -5,7 +5,8 @@ package types import ( "fmt" - + "github.com/hashicorp/consul/internal/catalog" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" "github.com/hashicorp/go-multierror" "github.com/hashicorp/consul/acl" @@ -44,11 +45,7 @@ func RegisterProxyStateTemplate(r resource.Registry) { // managed by a controller. return authorizer.ToAllowAuthorizer().OperatorWriteAllowed(authzContext) }, - List: func(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext) error { - // No-op List permission as we want to default to filtering resources - // from the list using the Read enforcement. - return nil - }, + List: resource.NoOpACLListHook, }, }) } @@ -96,6 +93,28 @@ func ValidateProxyStateTemplate(res *pbresource.Resource) error { })) } + if portErr := catalog.ValidateProtocol(pbcatalog.Protocol(cluster.Protocol)); portErr != nil { + merr = multierror.Append(merr, wrapClusterErr(resource.ErrInvalidField{ + Name: "protocol", + Wrapped: portErr, + })) + } + + if pbcatalog.Protocol(cluster.Protocol) == pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { + merr = multierror.Append(merr, wrapClusterErr(resource.ErrInvalidField{ + Name: "protocol", + Wrapped: resource.ErrMissing, + })) + } + + if pbcatalog.Protocol(cluster.Protocol) == pbcatalog.Protocol_PROTOCOL_MESH { + merr = multierror.Append(merr, wrapClusterErr(resource.ErrInvalidField{ + Name: "protocol", + Wrapped: fmt.Errorf("protocol %q is not a valid cluster traffic protocol", + cluster.Protocol.String()), + })) + } + wrapGroupErr := func(err error) error { return wrapClusterErr(resource.ErrInvalidField{ Name: "group", diff --git a/internal/mesh/internal/types/proxy_state_template_test.go b/internal/mesh/internal/types/proxy_state_template_test.go index 3f0216436f4e..d562a9c43a29 100644 --- a/internal/mesh/internal/types/proxy_state_template_test.go +++ b/internal/mesh/internal/types/proxy_state_template_test.go @@ -51,7 +51,8 @@ func TestValidateProxyStateTemplate(t *testing.T) { clusterForGroups := func(name string, groups ...*pbproxystate.EndpointGroup) *pbproxystate.Cluster { cluster := &pbproxystate.Cluster{ - Name: name, + Name: name, + Protocol: pbproxystate.Protocol_PROTOCOL_TCP, } require.NotEmpty(t, groups) @@ -83,6 +84,27 @@ func TestValidateProxyStateTemplate(t *testing.T) { // also empty map keys cases := map[string]testcase{ // ============== COMMON ============== + "cluster with invalid protocol": { + pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ + Name: "api-cluster", + Protocol: 100, + }), + expectErr: `invalid value of key "api-cluster" within clusters: invalid "protocol" field: not a supported enum value: 100`, + }, + "cluster with mesh protocol": { + pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ + Name: "api-cluster", + Protocol: pbproxystate.Protocol_PROTOCOL_MESH, + }), + expectErr: `invalid value of key "api-cluster" within clusters: invalid "protocol" field: protocol "PROTOCOL_MESH" is not a valid cluster traffic protocol`, + }, + "cluster with missing protocol": { + pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ + Name: "api-cluster", + Protocol: pbproxystate.Protocol_PROTOCOL_UNSPECIFIED, + }), + expectErr: `invalid value of key "api-cluster" within clusters: invalid "protocol" field: missing required field`, + }, "cluster with missing cluster group": { pst: pstForCluster("api-cluster", &pbproxystate.Cluster{ Name: "api-cluster", diff --git a/internal/mesh/internal/types/types.go b/internal/mesh/internal/types/types.go index 20b23604fc6e..cf1443aabf18 100644 --- a/internal/mesh/internal/types/types.go +++ b/internal/mesh/internal/types/types.go @@ -12,11 +12,12 @@ func Register(r resource.Registry) { RegisterComputedProxyConfiguration(r) RegisterDestinations(r) RegisterComputedExplicitDestinations(r) - RegisterUpstreamsConfiguration(r) RegisterProxyStateTemplate(r) RegisterHTTPRoute(r) RegisterTCPRoute(r) RegisterGRPCRoute(r) RegisterDestinationPolicy(r) RegisterComputedRoutes(r) + // todo (v2): uncomment once we implement it. + //RegisterDestinationsConfiguration(r) } diff --git a/internal/mesh/internal/types/types_test.go b/internal/mesh/internal/types/types_test.go index 631e1b4be8d0..801d3de01846 100644 --- a/internal/mesh/internal/types/types_test.go +++ b/internal/mesh/internal/types/types_test.go @@ -21,13 +21,14 @@ func TestTypeRegistration(t *testing.T) { requiredKinds := []string{ pbmesh.ProxyConfigurationKind, pbmesh.DestinationsKind, - pbmesh.DestinationsConfigurationKind, pbmesh.ProxyStateTemplateKind, pbmesh.HTTPRouteKind, pbmesh.TCPRouteKind, pbmesh.GRPCRouteKind, pbmesh.DestinationPolicyKind, pbmesh.ComputedRoutesKind, + // todo (v2): re-enable once we implement it. + //pbmesh.DestinationsConfigurationKind, } r := resource.NewRegistry() diff --git a/internal/mesh/internal/types/xroute.go b/internal/mesh/internal/types/xroute.go index 1c60bdcb1c54..619c9cb68243 100644 --- a/internal/mesh/internal/types/xroute.go +++ b/internal/mesh/internal/types/xroute.go @@ -290,7 +290,7 @@ func xRouteACLHooks[R XRouteData]() *resource.ACLHooks { hooks := &resource.ACLHooks{ Read: aclReadHookXRoute[R], Write: aclWriteHookXRoute[R], - List: aclListHookXRoute[R], + List: resource.NoOpACLListHook, } return hooks @@ -298,7 +298,7 @@ func xRouteACLHooks[R XRouteData]() *resource.ACLHooks { func aclReadHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error { if res == nil { - return resource.ErrNeedData + return resource.ErrNeedResource } dec, err := resource.Decode[R](res) @@ -351,9 +351,3 @@ func aclWriteHookXRoute[R XRouteData](authorizer acl.Authorizer, _ *acl.Authoriz return nil } - -func aclListHookXRoute[R XRouteData](authorizer acl.Authorizer, authzContext *acl.AuthorizerContext) error { - // No-op List permission as we want to default to filtering resources - // from the list using the Read enforcement. - return nil -} diff --git a/internal/mesh/internal/types/xroute_test.go b/internal/mesh/internal/types/xroute_test.go index 09806bea8c7e..5ba39e24cc07 100644 --- a/internal/mesh/internal/types/xroute_test.go +++ b/internal/mesh/internal/types/xroute_test.go @@ -12,7 +12,6 @@ import ( "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/wrapperspb" - "github.com/hashicorp/consul/acl" "github.com/hashicorp/consul/agent/structs" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/internal/resource/resourcetest" @@ -114,6 +113,7 @@ func getXRouteParentRefTestCases() map[string]xRouteParentRefTestcase { Port: port, } } + return map[string]xRouteParentRefTestcase{ "no parent refs": { routeTenancy: resource.DefaultNamespacedTenancy(), @@ -372,145 +372,160 @@ func testXRouteACLs[R XRouteData](t *testing.T, newRoute func(t *testing.T, pare userNewRoute := newRoute newRoute = func(t *testing.T, parentRefs, backendRefs []*pbresource.Reference) *pbresource.Resource { + require.NotEmpty(t, parentRefs) + require.NotEmpty(t, backendRefs) res := userNewRoute(t, parentRefs, backendRefs) + res.Id.Tenancy = parentRefs[0].Tenancy resourcetest.ValidateAndNormalize(t, registry, res) return res } - type testcase struct { - res *pbresource.Resource - rules string - check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource) - readOK string - writeOK string - } - const ( - DENY = "deny" - ALLOW = "allow" - DEFAULT = "default" + DENY = resourcetest.DENY + ALLOW = resourcetest.ALLOW + DEFAULT = resourcetest.DEFAULT ) - checkF := func(t *testing.T, name string, expect string, got error) { - switch expect { - case ALLOW: - if acl.IsErrPermissionDenied(got) { - t.Fatal(name + " should be allowed") - } - case DENY: - if !acl.IsErrPermissionDenied(got) { - t.Fatal(name + " should be denied") - } - case DEFAULT: - require.Nil(t, got, name+" expected fallthrough decision") - default: - t.Fatalf(name+" unexpected expectation: %q", expect) - } + serviceRef := func(tenancy, name string) *pbresource.Reference { + return newRefWithTenancy(pbcatalog.ServiceType, tenancy, name) } - resOneParentOneBackend := newRoute(t, - []*pbresource.Reference{ - newRef(pbcatalog.ServiceType, "api1"), - }, - []*pbresource.Reference{ - newRef(pbcatalog.ServiceType, "backend1"), - }, - ) - resTwoParentsOneBackend := newRoute(t, - []*pbresource.Reference{ - newRef(pbcatalog.ServiceType, "api1"), - newRef(pbcatalog.ServiceType, "api2"), - }, - []*pbresource.Reference{ - newRef(pbcatalog.ServiceType, "backend1"), - }, - ) - resOneParentTwoBackends := newRoute(t, - []*pbresource.Reference{ - newRef(pbcatalog.ServiceType, "api1"), - }, - []*pbresource.Reference{ - newRef(pbcatalog.ServiceType, "backend1"), - newRef(pbcatalog.ServiceType, "backend2"), - }, - ) - resTwoParentsTwoBackends := newRoute(t, - []*pbresource.Reference{ - newRef(pbcatalog.ServiceType, "api1"), - newRef(pbcatalog.ServiceType, "api2"), - }, - []*pbresource.Reference{ - newRef(pbcatalog.ServiceType, "backend1"), - newRef(pbcatalog.ServiceType, "backend2"), - }, - ) + resOneParentOneBackend := func(parentTenancy, backendTenancy string) *pbresource.Resource { + return newRoute(t, + []*pbresource.Reference{ + serviceRef(parentTenancy, "api1"), + }, + []*pbresource.Reference{ + serviceRef(backendTenancy, "backend1"), + }, + ) + } + resTwoParentsOneBackend := func(parentTenancy, backendTenancy string) *pbresource.Resource { + return newRoute(t, + []*pbresource.Reference{ + serviceRef(parentTenancy, "api1"), + serviceRef(parentTenancy, "api2"), + }, + []*pbresource.Reference{ + serviceRef(backendTenancy, "backend1"), + }, + ) + } + resOneParentTwoBackends := func(parentTenancy, backendTenancy string) *pbresource.Resource { + return newRoute(t, + []*pbresource.Reference{ + serviceRef(parentTenancy, "api1"), + }, + []*pbresource.Reference{ + serviceRef(backendTenancy, "backend1"), + serviceRef(backendTenancy, "backend2"), + }, + ) + } + resTwoParentsTwoBackends := func(parentTenancy, backendTenancy string) *pbresource.Resource { + return newRoute(t, + []*pbresource.Reference{ + serviceRef(parentTenancy, "api1"), + serviceRef(parentTenancy, "api2"), + }, + []*pbresource.Reference{ + serviceRef(backendTenancy, "backend1"), + serviceRef(backendTenancy, "backend2"), + }, + ) + } - run := func(t *testing.T, name string, tc testcase) { + run := func(t *testing.T, name string, tc resourcetest.ACLTestCase) { t.Run(name, func(t *testing.T) { - config := acl.Config{ - WildcardName: structs.WildcardSpecifier, - } - authz, err := acl.NewAuthorizerFromRules(tc.rules, &config, nil) - require.NoError(t, err) - authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) - - reg, ok := registry.Resolve(tc.res.Id.GetType()) - require.True(t, ok) - - err = reg.ACLs.Read(authz, &acl.AuthorizerContext{}, tc.res.Id, nil) - require.ErrorIs(t, err, resource.ErrNeedData, "read hook should require the data payload") - - checkF(t, "read", tc.readOK, reg.ACLs.Read(authz, &acl.AuthorizerContext{}, tc.res.Id, tc.res)) - checkF(t, "write", tc.writeOK, reg.ACLs.Write(authz, &acl.AuthorizerContext{}, tc.res)) - checkF(t, "list", DEFAULT, reg.ACLs.List(authz, &acl.AuthorizerContext{})) + resourcetest.RunACLTestCase(t, tc, registry) }) } - serviceRead := func(name string) string { + isEnterprise := (structs.NodeEnterpriseMetaInDefaultPartition().PartitionOrEmpty() == "default") + + serviceRead := func(partition, namespace, name string) string { + if isEnterprise { + return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "read" } } }`, partition, namespace, name) + } return fmt.Sprintf(` service %q { policy = "read" } `, name) } - serviceWrite := func(name string) string { + serviceWrite := func(partition, namespace, name string) string { + if isEnterprise { + return fmt.Sprintf(` partition %q { namespace %q { service %q { policy = "write" } } }`, partition, namespace, name) + } return fmt.Sprintf(` service %q { policy = "write" } `, name) } assert := func(t *testing.T, name string, rules string, res *pbresource.Resource, readOK, writeOK string) { - tc := testcase{ - res: res, - rules: rules, - readOK: readOK, - writeOK: writeOK, + tc := resourcetest.ACLTestCase{ + Rules: rules, + Res: res, + ReadOK: readOK, + WriteOK: writeOK, + ListOK: DEFAULT, + ReadHookRequiresResource: true, } run(t, name, tc) } - t.Run("no rules", func(t *testing.T) { - rules := `` - assert(t, "1parent 1backend", rules, resOneParentOneBackend, DENY, DENY) - assert(t, "1parent 2backends", rules, resOneParentTwoBackends, DENY, DENY) - assert(t, "2parents 1backend", rules, resTwoParentsOneBackend, DENY, DENY) - assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends, DENY, DENY) - }) - t.Run("api1:read", func(t *testing.T) { - rules := serviceRead("api1") - assert(t, "1parent 1backend", rules, resOneParentOneBackend, ALLOW, DENY) - assert(t, "1parent 2backends", rules, resOneParentTwoBackends, ALLOW, DENY) - assert(t, "2parents 1backend", rules, resTwoParentsOneBackend, DENY, DENY) - assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends, DENY, DENY) - }) - t.Run("api1:write", func(t *testing.T) { - rules := serviceWrite("api1") - assert(t, "1parent 1backend", rules, resOneParentOneBackend, ALLOW, DENY) - assert(t, "1parent 2backends", rules, resOneParentTwoBackends, ALLOW, DENY) - assert(t, "2parents 1backend", rules, resTwoParentsOneBackend, DENY, DENY) - assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends, DENY, DENY) - }) - t.Run("api1:write backend1:read", func(t *testing.T) { - rules := serviceWrite("api1") + serviceRead("backend1") - assert(t, "1parent 1backend", rules, resOneParentOneBackend, ALLOW, ALLOW) - assert(t, "1parent 2backends", rules, resOneParentTwoBackends, ALLOW, DENY) - assert(t, "2parents 1backend", rules, resTwoParentsOneBackend, DENY, DENY) - assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends, DENY, DENY) - }) + tenancies := []string{"default.default"} + if isEnterprise { + tenancies = append(tenancies, "default.foo", "alpha.default", "alpha.foo") + } + + for _, parentTenancyStr := range tenancies { + t.Run("route tenancy: "+parentTenancyStr, func(t *testing.T) { + for _, backendTenancyStr := range tenancies { + t.Run("backend tenancy: "+backendTenancyStr, func(t *testing.T) { + for _, aclTenancyStr := range tenancies { + t.Run("acl tenancy: "+aclTenancyStr, func(t *testing.T) { + aclTenancy := resourcetest.Tenancy(aclTenancyStr) + + maybe := func(match string, parentOnly bool) string { + if parentTenancyStr != aclTenancyStr { + return DENY + } + if !parentOnly && backendTenancyStr != aclTenancyStr { + return DENY + } + return match + } + + t.Run("no rules", func(t *testing.T) { + rules := `` + assert(t, "1parent 1backend", rules, resOneParentOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) + assert(t, "1parent 2backends", rules, resOneParentTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) + assert(t, "2parents 1backend", rules, resTwoParentsOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) + assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) + }) + t.Run("api1:read", func(t *testing.T) { + rules := serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "api1") + assert(t, "1parent 1backend", rules, resOneParentOneBackend(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) + assert(t, "1parent 2backends", rules, resOneParentTwoBackends(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) + assert(t, "2parents 1backend", rules, resTwoParentsOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) + assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) + }) + t.Run("api1:write", func(t *testing.T) { + rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api1") + assert(t, "1parent 1backend", rules, resOneParentOneBackend(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) + assert(t, "1parent 2backends", rules, resOneParentTwoBackends(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) + assert(t, "2parents 1backend", rules, resTwoParentsOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) + assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) + }) + t.Run("api1:write backend1:read", func(t *testing.T) { + rules := serviceWrite(aclTenancy.Partition, aclTenancy.Namespace, "api1") + + serviceRead(aclTenancy.Partition, aclTenancy.Namespace, "backend1") + assert(t, "1parent 1backend", rules, resOneParentOneBackend(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), maybe(ALLOW, false)) + assert(t, "1parent 2backends", rules, resOneParentTwoBackends(parentTenancyStr, backendTenancyStr), maybe(ALLOW, true), DENY) + assert(t, "2parents 1backend", rules, resTwoParentsOneBackend(parentTenancyStr, backendTenancyStr), DENY, DENY) + assert(t, "2parents 2backends", rules, resTwoParentsTwoBackends(parentTenancyStr, backendTenancyStr), DENY, DENY) + }) + }) + } + }) + } + }) + } } func newRef(typ *pbresource.Type, name string) *pbresource.Reference { diff --git a/internal/resource/acls.go b/internal/resource/acls.go new file mode 100644 index 000000000000..55a5872fc0de --- /dev/null +++ b/internal/resource/acls.go @@ -0,0 +1,13 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package resource + +import "github.com/hashicorp/consul/acl" + +// NoOpACLListHook is a common function that can be used if no special list permission is required for a resource. +func NoOpACLListHook(_ acl.Authorizer, _ *acl.AuthorizerContext) error { + // No-op List permission as we want to default to filtering resources + // from the list using the Read enforcement. + return nil +} diff --git a/internal/resource/demo/demo.go b/internal/resource/demo/demo.go index b6a9263842d3..8e978c9fb49a 100644 --- a/internal/resource/demo/demo.go +++ b/internal/resource/demo/demo.go @@ -97,7 +97,7 @@ func RegisterTypes(r resource.Registry) { readACL := func(authz acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, res *pbresource.Resource) error { if resource.EqualType(TypeV1RecordLabel, id.Type) { if res == nil { - return resource.ErrNeedData + return resource.ErrNeedResource } } key := fmt.Sprintf("resource/%s/%s", resource.ToGVK(id.Type), id.Name) diff --git a/internal/resource/errors.go b/internal/resource/errors.go index dbb624c8d004..24dd96e90ec4 100644 --- a/internal/resource/errors.go +++ b/internal/resource/errors.go @@ -5,15 +5,19 @@ package resource import ( "fmt" + "strings" - "github.com/hashicorp/consul/proto-public/pbresource" "google.golang.org/protobuf/reflect/protoreflect" + + "github.com/hashicorp/consul/proto-public/pbresource" ) var ( ErrMissing = NewConstError("missing required field") + ErrMissingOneOf = NewConstError("missing one of the required fields") ErrEmpty = NewConstError("cannot be empty") ErrReferenceTenancyNotEqual = NewConstError("resource tenancy and reference tenancy differ") + ErrUnsupported = NewConstError("field is currently not supported") ) // ConstError is more or less equivalent to the stdlib errors.errorstring. However, having @@ -133,6 +137,20 @@ type ErrOwnerTenantInvalid struct { } func (err ErrOwnerTenantInvalid) Error() string { + if err.ResourceTenancy == nil && err.OwnerTenancy != nil { + return fmt.Sprintf( + "empty resource tenancy cannot be owned by a resource in partition %s, namespace %s and peer %s", + err.OwnerTenancy.Partition, err.OwnerTenancy.Namespace, err.OwnerTenancy.PeerName, + ) + } + + if err.ResourceTenancy != nil && err.OwnerTenancy == nil { + return fmt.Sprintf( + "resource in partition %s, namespace %s and peer %s cannot be owned by a resource with empty tenancy", + err.ResourceTenancy.Partition, err.ResourceTenancy.Namespace, err.ResourceTenancy.PeerName, + ) + } + return fmt.Sprintf( "resource in partition %s, namespace %s and peer %s cannot be owned by a resource in partition %s, namespace %s and peer %s", err.ResourceTenancy.Partition, err.ResourceTenancy.Namespace, err.ResourceTenancy.PeerName, @@ -147,3 +165,17 @@ type ErrInvalidReferenceType struct { func (err ErrInvalidReferenceType) Error() string { return fmt.Sprintf("reference must have type %s", ToGVK(err.AllowedType)) } + +type ErrInvalidFields struct { + Names []string + Wrapped error +} + +func (err ErrInvalidFields) Error() string { + allFields := strings.Join(err.Names, ",") + return fmt.Sprintf("invalid %q fields: %v", allFields, err.Wrapped) +} + +func (err ErrInvalidFields) Unwrap() error { + return err.Wrapped +} diff --git a/internal/resource/protoc-gen-deepcopy/internal/generate/generate.go b/internal/resource/protoc-gen-deepcopy/internal/generate/generate.go index f9af3fa62a44..afa8dda7f621 100644 --- a/internal/resource/protoc-gen-deepcopy/internal/generate/generate.go +++ b/internal/resource/protoc-gen-deepcopy/internal/generate/generate.go @@ -37,8 +37,8 @@ func Generate(gen *protogen.Plugin) error { // Generate DeepCopyInto() method for this type p.P(`// DeepCopyInto supports using `, typeName, ` within kubernetes types, where deepcopy-gen is used.`) p.P(`func (in *`, typeName, `) DeepCopyInto(out *`, typeName, `) {`) - p.P(`p := `, protoIdent, `(in).(*`, typeName, `)`) - p.P(`*out = *p`) + p.P(`proto.Reset(out)`) + p.P(`proto.Merge(out,`, protoIdent, `(in))`) p.P(`}`) // Generate DeepCopy() method for this type diff --git a/internal/resource/registry.go b/internal/resource/registry.go index 2b004b6b4c0c..20c1f4dc41a8 100644 --- a/internal/resource/registry.go +++ b/internal/resource/registry.go @@ -68,14 +68,14 @@ type Registration struct { Scope Scope } -var ErrNeedData = errors.New("authorization check requires resource data") +var ErrNeedResource = errors.New("authorization check requires the entire resource") type ACLHooks struct { // Read is used to authorize Read RPCs and to filter results in List // RPCs. // // It can be called an ID and possibly a Resource. The check will first - // attempt to use the ID and if the hook returns ErrNeedData, then the + // attempt to use the ID and if the hook returns ErrNeedResource, then the // check will be deferred until the data is fetched from the storage layer. // // If it is omitted, `operator:read` permission is assumed. diff --git a/internal/resource/resourcetest/acls.go b/internal/resource/resourcetest/acls.go new file mode 100644 index 000000000000..3f77c7fec490 --- /dev/null +++ b/internal/resource/resourcetest/acls.go @@ -0,0 +1,119 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package resourcetest + +import ( + "testing" + + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/reflect/protoreflect" + + "github.com/hashicorp/consul/acl" + "github.com/hashicorp/consul/agent/structs" + "github.com/hashicorp/consul/internal/resource" + "github.com/hashicorp/consul/proto-public/pbresource" +) + +const ( + DENY = "deny" + ALLOW = "allow" + DEFAULT = "default" +) + +var checkF = func(t *testing.T, expect string, got error) { + switch expect { + case ALLOW: + if acl.IsErrPermissionDenied(got) { + t.Fatal("should be allowed") + } + case DENY: + if !acl.IsErrPermissionDenied(got) { + t.Fatal("should be denied") + } + case DEFAULT: + require.Nil(t, got, "expected fallthrough decision") + default: + t.Fatalf("unexpected expectation: %q", expect) + } +} + +type ACLTestCase struct { + Rules string + + // AuthCtx is optional. If not provided an empty one will be used. + AuthCtx *acl.AuthorizerContext + + // One of either Res or Data/Owner/Typ should be set. + Res *pbresource.Resource + Data protoreflect.ProtoMessage + Owner *pbresource.ID + Typ *pbresource.Type + + ReadOK string + WriteOK string + ListOK string + + ReadHookRequiresResource bool +} + +func RunACLTestCase(t *testing.T, tc ACLTestCase, registry resource.Registry) { + var ( + typ *pbresource.Type + res *pbresource.Resource + ) + if tc.Res != nil { + require.Nil(t, tc.Data) + require.Nil(t, tc.Owner) + require.Nil(t, tc.Typ) + typ = tc.Res.Id.GetType() + res = tc.Res + } else { + require.NotNil(t, tc.Data) + require.NotNil(t, tc.Typ) + typ = tc.Typ + + resolvedType, ok := registry.Resolve(typ) + require.True(t, ok) + + res = Resource(tc.Typ, "test"). + WithTenancy(DefaultTenancyForType(t, resolvedType)). + WithOwner(tc.Owner). + WithData(t, tc.Data). + Build() + } + + reg, ok := registry.Resolve(typ) + require.True(t, ok) + + ValidateAndNormalize(t, registry, res) + + config := acl.Config{ + WildcardName: structs.WildcardSpecifier, + } + authz, err := acl.NewAuthorizerFromRules(tc.Rules, &config, nil) + require.NoError(t, err) + authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()}) + + if tc.AuthCtx == nil { + tc.AuthCtx = &acl.AuthorizerContext{} + } + + if tc.ReadHookRequiresResource { + err = reg.ACLs.Read(authz, tc.AuthCtx, res.Id, nil) + require.ErrorIs(t, err, resource.ErrNeedResource, "read hook should require the data payload") + } + + t.Run("read", func(t *testing.T) { + err := reg.ACLs.Read(authz, tc.AuthCtx, res.Id, res) + checkF(t, tc.ReadOK, err) + }) + t.Run("write", func(t *testing.T) { + err := reg.ACLs.Write(authz, tc.AuthCtx, res) + checkF(t, tc.WriteOK, err) + }) + t.Run("list", func(t *testing.T) { + err := reg.ACLs.List(authz, tc.AuthCtx) + checkF(t, tc.ListOK, err) + }) +} diff --git a/internal/resource/resourcetest/tenancy.go b/internal/resource/resourcetest/tenancy.go index 838379cebbed..5f5c0525b6f4 100644 --- a/internal/resource/resourcetest/tenancy.go +++ b/internal/resource/resourcetest/tenancy.go @@ -5,6 +5,7 @@ package resourcetest import ( "strings" + "testing" "github.com/hashicorp/consul/internal/resource" "github.com/hashicorp/consul/proto-public/pbresource" @@ -35,3 +36,17 @@ func Tenancy(s string) *pbresource.Tenancy { return &pbresource.Tenancy{Partition: "BAD", Namespace: "BAD", PeerName: "BAD"} } } + +func DefaultTenancyForType(t *testing.T, reg resource.Registration) *pbresource.Tenancy { + switch reg.Scope { + case resource.ScopeNamespace: + return resource.DefaultNamespacedTenancy() + case resource.ScopePartition: + return resource.DefaultPartitionedTenancy() + case resource.ScopeCluster: + return resource.DefaultClusteredTenancy() + default: + t.Fatalf("unsupported resource scope: %v", reg.Scope) + return nil + } +} diff --git a/internal/testing/golden/golden.go b/internal/testing/golden/golden.go index 8145d16814bf..a4d971d0d096 100644 --- a/internal/testing/golden/golden.go +++ b/internal/testing/golden/golden.go @@ -42,7 +42,15 @@ func GetBytes(t *testing.T, actual, filename string) []byte { require.NoError(t, err) } - expected, err := os.ReadFile(path) + return GetBytesAtFilePath(t, path) +} + +// GetBytes reads the expected value from the file at filepath and returns the +// value as a byte array. filepath is relative to the ./testdata directory. +func GetBytesAtFilePath(t *testing.T, filepath string) []byte { + t.Helper() + + expected, err := os.ReadFile(filepath) require.NoError(t, err) return expected } diff --git a/proto-public/annotations/ratelimit/ratelimit_deepcopy.gen.go b/proto-public/annotations/ratelimit/ratelimit_deepcopy.gen.go index 72ef4d990c62..6c1c69633734 100644 --- a/proto-public/annotations/ratelimit/ratelimit_deepcopy.gen.go +++ b/proto-public/annotations/ratelimit/ratelimit_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Spec within kubernetes types, where deepcopy-gen is used. func (in *Spec) DeepCopyInto(out *Spec) { - p := proto.Clone(in).(*Spec) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Spec. Required by controller-gen. diff --git a/proto-public/go.mod b/proto-public/go.mod index b77474df64bb..ab00c6c62e2c 100644 --- a/proto-public/go.mod +++ b/proto-public/go.mod @@ -5,7 +5,7 @@ go 1.19 require ( github.com/stretchr/testify v1.8.3 golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 - google.golang.org/grpc v1.55.0 + google.golang.org/grpc v1.56.3 google.golang.org/protobuf v1.30.0 ) @@ -16,9 +16,9 @@ require ( github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect github.com/stretchr/objx v0.5.0 // indirect - golang.org/x/net v0.13.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.11.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/proto-public/go.sum b/proto-public/go.sum index ffb9a0538ca9..f11647a8490e 100644 --- a/proto-public/go.sum +++ b/proto-public/go.sum @@ -32,17 +32,17 @@ github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gt github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 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/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= 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.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= diff --git a/proto-public/pbacl/acl_deepcopy.gen.go b/proto-public/pbacl/acl_deepcopy.gen.go index 9bf1dcb45766..b3b069fe1fc8 100644 --- a/proto-public/pbacl/acl_deepcopy.gen.go +++ b/proto-public/pbacl/acl_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using LogoutResponse within kubernetes types, where deepcopy-gen is used. func (in *LogoutResponse) DeepCopyInto(out *LogoutResponse) { - p := proto.Clone(in).(*LogoutResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LogoutResponse. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *LogoutResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using LoginRequest within kubernetes types, where deepcopy-gen is used. func (in *LoginRequest) DeepCopyInto(out *LoginRequest) { - p := proto.Clone(in).(*LoginRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginRequest. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *LoginRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using LoginResponse within kubernetes types, where deepcopy-gen is used. func (in *LoginResponse) DeepCopyInto(out *LoginResponse) { - p := proto.Clone(in).(*LoginResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginResponse. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *LoginResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using LoginToken within kubernetes types, where deepcopy-gen is used. func (in *LoginToken) DeepCopyInto(out *LoginToken) { - p := proto.Clone(in).(*LoginToken) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginToken. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *LoginToken) DeepCopyInterface() interface{} { // DeepCopyInto supports using LogoutRequest within kubernetes types, where deepcopy-gen is used. func (in *LogoutRequest) DeepCopyInto(out *LogoutRequest) { - p := proto.Clone(in).(*LogoutRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LogoutRequest. Required by controller-gen. diff --git a/proto-public/pbauth/v2beta1/computed_traffic_permissions_deepcopy.gen.go b/proto-public/pbauth/v2beta1/computed_traffic_permissions_deepcopy.gen.go index b0b3baa08721..7c22d2285c2d 100644 --- a/proto-public/pbauth/v2beta1/computed_traffic_permissions_deepcopy.gen.go +++ b/proto-public/pbauth/v2beta1/computed_traffic_permissions_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ComputedTrafficPermissions within kubernetes types, where deepcopy-gen is used. func (in *ComputedTrafficPermissions) DeepCopyInto(out *ComputedTrafficPermissions) { - p := proto.Clone(in).(*ComputedTrafficPermissions) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTrafficPermissions. Required by controller-gen. diff --git a/proto-public/pbauth/v2beta1/traffic_permissions_deepcopy.gen.go b/proto-public/pbauth/v2beta1/traffic_permissions_deepcopy.gen.go index 177c60c14a89..b954d00b407f 100644 --- a/proto-public/pbauth/v2beta1/traffic_permissions_deepcopy.gen.go +++ b/proto-public/pbauth/v2beta1/traffic_permissions_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using TrafficPermissions within kubernetes types, where deepcopy-gen is used. func (in *TrafficPermissions) DeepCopyInto(out *TrafficPermissions) { - p := proto.Clone(in).(*TrafficPermissions) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficPermissions. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *TrafficPermissions) DeepCopyInterface() interface{} { // DeepCopyInto supports using NamespaceTrafficPermissions within kubernetes types, where deepcopy-gen is used. func (in *NamespaceTrafficPermissions) DeepCopyInto(out *NamespaceTrafficPermissions) { - p := proto.Clone(in).(*NamespaceTrafficPermissions) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NamespaceTrafficPermissions. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *NamespaceTrafficPermissions) DeepCopyInterface() interface{} { // DeepCopyInto supports using PartitionTrafficPermissions within kubernetes types, where deepcopy-gen is used. func (in *PartitionTrafficPermissions) DeepCopyInto(out *PartitionTrafficPermissions) { - p := proto.Clone(in).(*PartitionTrafficPermissions) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PartitionTrafficPermissions. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *PartitionTrafficPermissions) DeepCopyInterface() interface{} { // DeepCopyInto supports using Destination within kubernetes types, where deepcopy-gen is used. func (in *Destination) DeepCopyInto(out *Destination) { - p := proto.Clone(in).(*Destination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Destination. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *Destination) DeepCopyInterface() interface{} { // DeepCopyInto supports using Permission within kubernetes types, where deepcopy-gen is used. func (in *Permission) DeepCopyInto(out *Permission) { - p := proto.Clone(in).(*Permission) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Permission. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *Permission) DeepCopyInterface() interface{} { // DeepCopyInto supports using Source within kubernetes types, where deepcopy-gen is used. func (in *Source) DeepCopyInto(out *Source) { - p := proto.Clone(in).(*Source) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Source. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *Source) DeepCopyInterface() interface{} { // DeepCopyInto supports using ExcludeSource within kubernetes types, where deepcopy-gen is used. func (in *ExcludeSource) DeepCopyInto(out *ExcludeSource) { - p := proto.Clone(in).(*ExcludeSource) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExcludeSource. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *ExcludeSource) DeepCopyInterface() interface{} { // DeepCopyInto supports using DestinationRule within kubernetes types, where deepcopy-gen is used. func (in *DestinationRule) DeepCopyInto(out *DestinationRule) { - p := proto.Clone(in).(*DestinationRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRule. Required by controller-gen. @@ -175,8 +175,8 @@ func (in *DestinationRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using ExcludePermissionRule within kubernetes types, where deepcopy-gen is used. func (in *ExcludePermissionRule) DeepCopyInto(out *ExcludePermissionRule) { - p := proto.Clone(in).(*ExcludePermissionRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExcludePermissionRule. Required by controller-gen. @@ -196,8 +196,8 @@ func (in *ExcludePermissionRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using DestinationRuleHeader within kubernetes types, where deepcopy-gen is used. func (in *DestinationRuleHeader) DeepCopyInto(out *DestinationRuleHeader) { - p := proto.Clone(in).(*DestinationRuleHeader) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRuleHeader. Required by controller-gen. diff --git a/proto-public/pbauth/v2beta1/workload_identity_deepcopy.gen.go b/proto-public/pbauth/v2beta1/workload_identity_deepcopy.gen.go index 7684b5ef837f..7a25aba74a48 100644 --- a/proto-public/pbauth/v2beta1/workload_identity_deepcopy.gen.go +++ b/proto-public/pbauth/v2beta1/workload_identity_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using WorkloadIdentity within kubernetes types, where deepcopy-gen is used. func (in *WorkloadIdentity) DeepCopyInto(out *WorkloadIdentity) { - p := proto.Clone(in).(*WorkloadIdentity) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadIdentity. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/dns_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/dns_deepcopy.gen.go index f2a7b3564fc9..9a3d883b8cec 100644 --- a/proto-public/pbcatalog/v2beta1/dns_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/dns_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using DNSPolicy within kubernetes types, where deepcopy-gen is used. func (in *DNSPolicy) DeepCopyInto(out *DNSPolicy) { - p := proto.Clone(in).(*DNSPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSPolicy. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *DNSPolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using Weights within kubernetes types, where deepcopy-gen is used. func (in *Weights) DeepCopyInto(out *Weights) { - p := proto.Clone(in).(*Weights) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Weights. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/failover_policy_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/failover_policy_deepcopy.gen.go index b0fc57e9723d..fabe3f9e30a6 100644 --- a/proto-public/pbcatalog/v2beta1/failover_policy_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/failover_policy_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using FailoverPolicy within kubernetes types, where deepcopy-gen is used. func (in *FailoverPolicy) DeepCopyInto(out *FailoverPolicy) { - p := proto.Clone(in).(*FailoverPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverPolicy. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *FailoverPolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using FailoverConfig within kubernetes types, where deepcopy-gen is used. func (in *FailoverConfig) DeepCopyInto(out *FailoverConfig) { - p := proto.Clone(in).(*FailoverConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverConfig. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *FailoverConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using FailoverDestination within kubernetes types, where deepcopy-gen is used. func (in *FailoverDestination) DeepCopyInto(out *FailoverDestination) { - p := proto.Clone(in).(*FailoverDestination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverDestination. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/health_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/health_deepcopy.gen.go index bb24cbe052fd..677a1af1056d 100644 --- a/proto-public/pbcatalog/v2beta1/health_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/health_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using HealthStatus within kubernetes types, where deepcopy-gen is used. func (in *HealthStatus) DeepCopyInto(out *HealthStatus) { - p := proto.Clone(in).(*HealthStatus) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthStatus. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *HealthStatus) DeepCopyInterface() interface{} { // DeepCopyInto supports using HealthChecks within kubernetes types, where deepcopy-gen is used. func (in *HealthChecks) DeepCopyInto(out *HealthChecks) { - p := proto.Clone(in).(*HealthChecks) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthChecks. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *HealthChecks) DeepCopyInterface() interface{} { // DeepCopyInto supports using HealthCheck within kubernetes types, where deepcopy-gen is used. func (in *HealthCheck) DeepCopyInto(out *HealthCheck) { - p := proto.Clone(in).(*HealthCheck) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthCheck. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *HealthCheck) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPCheck within kubernetes types, where deepcopy-gen is used. func (in *HTTPCheck) DeepCopyInto(out *HTTPCheck) { - p := proto.Clone(in).(*HTTPCheck) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPCheck. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *HTTPCheck) DeepCopyInterface() interface{} { // DeepCopyInto supports using TCPCheck within kubernetes types, where deepcopy-gen is used. func (in *TCPCheck) DeepCopyInto(out *TCPCheck) { - p := proto.Clone(in).(*TCPCheck) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPCheck. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *TCPCheck) DeepCopyInterface() interface{} { // DeepCopyInto supports using UDPCheck within kubernetes types, where deepcopy-gen is used. func (in *UDPCheck) DeepCopyInto(out *UDPCheck) { - p := proto.Clone(in).(*UDPCheck) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UDPCheck. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *UDPCheck) DeepCopyInterface() interface{} { // DeepCopyInto supports using GRPCCheck within kubernetes types, where deepcopy-gen is used. func (in *GRPCCheck) DeepCopyInto(out *GRPCCheck) { - p := proto.Clone(in).(*GRPCCheck) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCCheck. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *GRPCCheck) DeepCopyInterface() interface{} { // DeepCopyInto supports using OSServiceCheck within kubernetes types, where deepcopy-gen is used. func (in *OSServiceCheck) DeepCopyInto(out *OSServiceCheck) { - p := proto.Clone(in).(*OSServiceCheck) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OSServiceCheck. Required by controller-gen. @@ -175,8 +175,8 @@ func (in *OSServiceCheck) DeepCopyInterface() interface{} { // DeepCopyInto supports using CheckTLSConfig within kubernetes types, where deepcopy-gen is used. func (in *CheckTLSConfig) DeepCopyInto(out *CheckTLSConfig) { - p := proto.Clone(in).(*CheckTLSConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheckTLSConfig. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/node_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/node_deepcopy.gen.go index 775faa3d535f..d864f7858fe6 100644 --- a/proto-public/pbcatalog/v2beta1/node_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/node_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Node within kubernetes types, where deepcopy-gen is used. func (in *Node) DeepCopyInto(out *Node) { - p := proto.Clone(in).(*Node) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Node. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Node) DeepCopyInterface() interface{} { // DeepCopyInto supports using NodeAddress within kubernetes types, where deepcopy-gen is used. func (in *NodeAddress) DeepCopyInto(out *NodeAddress) { - p := proto.Clone(in).(*NodeAddress) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAddress. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/selector_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/selector_deepcopy.gen.go index 1f4ae1c7ff52..7e59d5588081 100644 --- a/proto-public/pbcatalog/v2beta1/selector_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/selector_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using WorkloadSelector within kubernetes types, where deepcopy-gen is used. func (in *WorkloadSelector) DeepCopyInto(out *WorkloadSelector) { - p := proto.Clone(in).(*WorkloadSelector) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadSelector. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/service_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/service_deepcopy.gen.go index 92e77ecb9d44..fa578cc34464 100644 --- a/proto-public/pbcatalog/v2beta1/service_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/service_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Service within kubernetes types, where deepcopy-gen is used. func (in *Service) DeepCopyInto(out *Service) { - p := proto.Clone(in).(*Service) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Service. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Service) DeepCopyInterface() interface{} { // DeepCopyInto supports using ServicePort within kubernetes types, where deepcopy-gen is used. func (in *ServicePort) DeepCopyInto(out *ServicePort) { - p := proto.Clone(in).(*ServicePort) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServicePort. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/service_endpoints_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/service_endpoints_deepcopy.gen.go index 6c1e3833bf41..f3634c091be7 100644 --- a/proto-public/pbcatalog/v2beta1/service_endpoints_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/service_endpoints_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ServiceEndpoints within kubernetes types, where deepcopy-gen is used. func (in *ServiceEndpoints) DeepCopyInto(out *ServiceEndpoints) { - p := proto.Clone(in).(*ServiceEndpoints) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceEndpoints. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *ServiceEndpoints) DeepCopyInterface() interface{} { // DeepCopyInto supports using Endpoint within kubernetes types, where deepcopy-gen is used. func (in *Endpoint) DeepCopyInto(out *Endpoint) { - p := proto.Clone(in).(*Endpoint) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/vip_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/vip_deepcopy.gen.go index d49da5045ba2..8308240c52b0 100644 --- a/proto-public/pbcatalog/v2beta1/vip_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/vip_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using VirtualIPs within kubernetes types, where deepcopy-gen is used. func (in *VirtualIPs) DeepCopyInto(out *VirtualIPs) { - p := proto.Clone(in).(*VirtualIPs) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualIPs. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *VirtualIPs) DeepCopyInterface() interface{} { // DeepCopyInto supports using IP within kubernetes types, where deepcopy-gen is used. func (in *IP) DeepCopyInto(out *IP) { - p := proto.Clone(in).(*IP) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IP. Required by controller-gen. diff --git a/proto-public/pbcatalog/v2beta1/workload_deepcopy.gen.go b/proto-public/pbcatalog/v2beta1/workload_deepcopy.gen.go index fbb4b50af325..10d71872bf6d 100644 --- a/proto-public/pbcatalog/v2beta1/workload_deepcopy.gen.go +++ b/proto-public/pbcatalog/v2beta1/workload_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Workload within kubernetes types, where deepcopy-gen is used. func (in *Workload) DeepCopyInto(out *Workload) { - p := proto.Clone(in).(*Workload) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Workload. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Workload) DeepCopyInterface() interface{} { // DeepCopyInto supports using WorkloadAddress within kubernetes types, where deepcopy-gen is used. func (in *WorkloadAddress) DeepCopyInto(out *WorkloadAddress) { - p := proto.Clone(in).(*WorkloadAddress) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadAddress. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *WorkloadAddress) DeepCopyInterface() interface{} { // DeepCopyInto supports using WorkloadPort within kubernetes types, where deepcopy-gen is used. func (in *WorkloadPort) DeepCopyInto(out *WorkloadPort) { - p := proto.Clone(in).(*WorkloadPort) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadPort. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *WorkloadPort) DeepCopyInterface() interface{} { // DeepCopyInto supports using Locality within kubernetes types, where deepcopy-gen is used. func (in *Locality) DeepCopyInto(out *Locality) { - p := proto.Clone(in).(*Locality) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Locality. Required by controller-gen. diff --git a/proto-public/pbconnectca/ca_deepcopy.gen.go b/proto-public/pbconnectca/ca_deepcopy.gen.go index 5200e4d9cac7..8ac221b224c5 100644 --- a/proto-public/pbconnectca/ca_deepcopy.gen.go +++ b/proto-public/pbconnectca/ca_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using WatchRootsRequest within kubernetes types, where deepcopy-gen is used. func (in *WatchRootsRequest) DeepCopyInto(out *WatchRootsRequest) { - p := proto.Clone(in).(*WatchRootsRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRootsRequest. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *WatchRootsRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using WatchRootsResponse within kubernetes types, where deepcopy-gen is used. func (in *WatchRootsResponse) DeepCopyInto(out *WatchRootsResponse) { - p := proto.Clone(in).(*WatchRootsResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchRootsResponse. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *WatchRootsResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using CARoot within kubernetes types, where deepcopy-gen is used. func (in *CARoot) DeepCopyInto(out *CARoot) { - p := proto.Clone(in).(*CARoot) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CARoot. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *CARoot) DeepCopyInterface() interface{} { // DeepCopyInto supports using SignRequest within kubernetes types, where deepcopy-gen is used. func (in *SignRequest) DeepCopyInto(out *SignRequest) { - p := proto.Clone(in).(*SignRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignRequest. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *SignRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using SignResponse within kubernetes types, where deepcopy-gen is used. func (in *SignResponse) DeepCopyInto(out *SignResponse) { - p := proto.Clone(in).(*SignResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SignResponse. Required by controller-gen. diff --git a/proto-public/pbdataplane/dataplane_deepcopy.gen.go b/proto-public/pbdataplane/dataplane_deepcopy.gen.go index 1d787b70721d..e1daf2b699fb 100644 --- a/proto-public/pbdataplane/dataplane_deepcopy.gen.go +++ b/proto-public/pbdataplane/dataplane_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using GetSupportedDataplaneFeaturesRequest within kubernetes types, where deepcopy-gen is used. func (in *GetSupportedDataplaneFeaturesRequest) DeepCopyInto(out *GetSupportedDataplaneFeaturesRequest) { - p := proto.Clone(in).(*GetSupportedDataplaneFeaturesRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetSupportedDataplaneFeaturesRequest. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *GetSupportedDataplaneFeaturesRequest) DeepCopyInterface() interface{} // DeepCopyInto supports using DataplaneFeatureSupport within kubernetes types, where deepcopy-gen is used. func (in *DataplaneFeatureSupport) DeepCopyInto(out *DataplaneFeatureSupport) { - p := proto.Clone(in).(*DataplaneFeatureSupport) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DataplaneFeatureSupport. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *DataplaneFeatureSupport) DeepCopyInterface() interface{} { // DeepCopyInto supports using GetSupportedDataplaneFeaturesResponse within kubernetes types, where deepcopy-gen is used. func (in *GetSupportedDataplaneFeaturesResponse) DeepCopyInto(out *GetSupportedDataplaneFeaturesResponse) { - p := proto.Clone(in).(*GetSupportedDataplaneFeaturesResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetSupportedDataplaneFeaturesResponse. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *GetSupportedDataplaneFeaturesResponse) DeepCopyInterface() interface{} // DeepCopyInto supports using GetEnvoyBootstrapParamsRequest within kubernetes types, where deepcopy-gen is used. func (in *GetEnvoyBootstrapParamsRequest) DeepCopyInto(out *GetEnvoyBootstrapParamsRequest) { - p := proto.Clone(in).(*GetEnvoyBootstrapParamsRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetEnvoyBootstrapParamsRequest. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *GetEnvoyBootstrapParamsRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using GetEnvoyBootstrapParamsResponse within kubernetes types, where deepcopy-gen is used. func (in *GetEnvoyBootstrapParamsResponse) DeepCopyInto(out *GetEnvoyBootstrapParamsResponse) { - p := proto.Clone(in).(*GetEnvoyBootstrapParamsResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetEnvoyBootstrapParamsResponse. Required by controller-gen. diff --git a/proto-public/pbdns/dns_deepcopy.gen.go b/proto-public/pbdns/dns_deepcopy.gen.go index c2975e2d7f9a..339ab448e1d1 100644 --- a/proto-public/pbdns/dns_deepcopy.gen.go +++ b/proto-public/pbdns/dns_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using QueryRequest within kubernetes types, where deepcopy-gen is used. func (in *QueryRequest) DeepCopyInto(out *QueryRequest) { - p := proto.Clone(in).(*QueryRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryRequest. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *QueryRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using QueryResponse within kubernetes types, where deepcopy-gen is used. func (in *QueryResponse) DeepCopyInto(out *QueryResponse) { - p := proto.Clone(in).(*QueryResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryResponse. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/common_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/common_deepcopy.gen.go index dae015adf7ce..f9aa662c4182 100644 --- a/proto-public/pbmesh/v2beta1/common_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/common_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ParentReference within kubernetes types, where deepcopy-gen is used. func (in *ParentReference) DeepCopyInto(out *ParentReference) { - p := proto.Clone(in).(*ParentReference) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ParentReference. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *ParentReference) DeepCopyInterface() interface{} { // DeepCopyInto supports using BackendReference within kubernetes types, where deepcopy-gen is used. func (in *BackendReference) DeepCopyInto(out *BackendReference) { - p := proto.Clone(in).(*BackendReference) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendReference. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/computed_explicit_destinations_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/computed_explicit_destinations_deepcopy.gen.go index 3e237e2ac009..7a14e57454f2 100644 --- a/proto-public/pbmesh/v2beta1/computed_explicit_destinations_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/computed_explicit_destinations_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ComputedExplicitDestinations within kubernetes types, where deepcopy-gen is used. func (in *ComputedExplicitDestinations) DeepCopyInto(out *ComputedExplicitDestinations) { - p := proto.Clone(in).(*ComputedExplicitDestinations) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedExplicitDestinations. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/computed_proxy_configuration_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/computed_proxy_configuration_deepcopy.gen.go index c8d608122268..d6eb5723030b 100644 --- a/proto-public/pbmesh/v2beta1/computed_proxy_configuration_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/computed_proxy_configuration_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ComputedProxyConfiguration within kubernetes types, where deepcopy-gen is used. func (in *ComputedProxyConfiguration) DeepCopyInto(out *ComputedProxyConfiguration) { - p := proto.Clone(in).(*ComputedProxyConfiguration) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedProxyConfiguration. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/computed_routes_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/computed_routes_deepcopy.gen.go index 01e077aacf00..d63358455892 100644 --- a/proto-public/pbmesh/v2beta1/computed_routes_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/computed_routes_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ComputedRoutes within kubernetes types, where deepcopy-gen is used. func (in *ComputedRoutes) DeepCopyInto(out *ComputedRoutes) { - p := proto.Clone(in).(*ComputedRoutes) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedRoutes. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *ComputedRoutes) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedPortRoutes within kubernetes types, where deepcopy-gen is used. func (in *ComputedPortRoutes) DeepCopyInto(out *ComputedPortRoutes) { - p := proto.Clone(in).(*ComputedPortRoutes) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedPortRoutes. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *ComputedPortRoutes) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedHTTPRoute within kubernetes types, where deepcopy-gen is used. func (in *ComputedHTTPRoute) DeepCopyInto(out *ComputedHTTPRoute) { - p := proto.Clone(in).(*ComputedHTTPRoute) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPRoute. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *ComputedHTTPRoute) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedHTTPRouteRule within kubernetes types, where deepcopy-gen is used. func (in *ComputedHTTPRouteRule) DeepCopyInto(out *ComputedHTTPRouteRule) { - p := proto.Clone(in).(*ComputedHTTPRouteRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPRouteRule. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *ComputedHTTPRouteRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedHTTPBackendRef within kubernetes types, where deepcopy-gen is used. func (in *ComputedHTTPBackendRef) DeepCopyInto(out *ComputedHTTPBackendRef) { - p := proto.Clone(in).(*ComputedHTTPBackendRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedHTTPBackendRef. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *ComputedHTTPBackendRef) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedGRPCRoute within kubernetes types, where deepcopy-gen is used. func (in *ComputedGRPCRoute) DeepCopyInto(out *ComputedGRPCRoute) { - p := proto.Clone(in).(*ComputedGRPCRoute) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCRoute. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *ComputedGRPCRoute) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedGRPCRouteRule within kubernetes types, where deepcopy-gen is used. func (in *ComputedGRPCRouteRule) DeepCopyInto(out *ComputedGRPCRouteRule) { - p := proto.Clone(in).(*ComputedGRPCRouteRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCRouteRule. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *ComputedGRPCRouteRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedGRPCBackendRef within kubernetes types, where deepcopy-gen is used. func (in *ComputedGRPCBackendRef) DeepCopyInto(out *ComputedGRPCBackendRef) { - p := proto.Clone(in).(*ComputedGRPCBackendRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedGRPCBackendRef. Required by controller-gen. @@ -175,8 +175,8 @@ func (in *ComputedGRPCBackendRef) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedTCPRoute within kubernetes types, where deepcopy-gen is used. func (in *ComputedTCPRoute) DeepCopyInto(out *ComputedTCPRoute) { - p := proto.Clone(in).(*ComputedTCPRoute) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPRoute. Required by controller-gen. @@ -196,8 +196,8 @@ func (in *ComputedTCPRoute) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedTCPRouteRule within kubernetes types, where deepcopy-gen is used. func (in *ComputedTCPRouteRule) DeepCopyInto(out *ComputedTCPRouteRule) { - p := proto.Clone(in).(*ComputedTCPRouteRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPRouteRule. Required by controller-gen. @@ -217,8 +217,8 @@ func (in *ComputedTCPRouteRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedTCPBackendRef within kubernetes types, where deepcopy-gen is used. func (in *ComputedTCPBackendRef) DeepCopyInto(out *ComputedTCPBackendRef) { - p := proto.Clone(in).(*ComputedTCPBackendRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedTCPBackendRef. Required by controller-gen. @@ -238,8 +238,8 @@ func (in *ComputedTCPBackendRef) DeepCopyInterface() interface{} { // DeepCopyInto supports using BackendTargetDetails within kubernetes types, where deepcopy-gen is used. func (in *BackendTargetDetails) DeepCopyInto(out *BackendTargetDetails) { - p := proto.Clone(in).(*BackendTargetDetails) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendTargetDetails. Required by controller-gen. @@ -259,8 +259,8 @@ func (in *BackendTargetDetails) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedFailoverConfig within kubernetes types, where deepcopy-gen is used. func (in *ComputedFailoverConfig) DeepCopyInto(out *ComputedFailoverConfig) { - p := proto.Clone(in).(*ComputedFailoverConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedFailoverConfig. Required by controller-gen. @@ -280,8 +280,8 @@ func (in *ComputedFailoverConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using ComputedFailoverDestination within kubernetes types, where deepcopy-gen is used. func (in *ComputedFailoverDestination) DeepCopyInto(out *ComputedFailoverDestination) { - p := proto.Clone(in).(*ComputedFailoverDestination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputedFailoverDestination. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/connection.pb.go b/proto-public/pbmesh/v2beta1/connection.pb.go index d8ccaba7d74e..591df222fc93 100644 --- a/proto-public/pbmesh/v2beta1/connection.pb.go +++ b/proto-public/pbmesh/v2beta1/connection.pb.go @@ -137,8 +137,8 @@ type InboundConnectionsConfig struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - MaxInboundConnections uint64 `protobuf:"varint,12,opt,name=max_inbound_connections,json=maxInboundConnections,proto3" json:"max_inbound_connections,omitempty"` - BalanceInboundConnections BalanceConnections `protobuf:"varint,13,opt,name=balance_inbound_connections,json=balanceInboundConnections,proto3,enum=hashicorp.consul.mesh.v2beta1.BalanceConnections" json:"balance_inbound_connections,omitempty"` + MaxInboundConnections uint32 `protobuf:"varint,1,opt,name=max_inbound_connections,json=maxInboundConnections,proto3" json:"max_inbound_connections,omitempty"` + BalanceInboundConnections BalanceConnections `protobuf:"varint,2,opt,name=balance_inbound_connections,json=balanceInboundConnections,proto3,enum=hashicorp.consul.mesh.v2beta1.BalanceConnections" json:"balance_inbound_connections,omitempty"` } func (x *InboundConnectionsConfig) Reset() { @@ -173,7 +173,7 @@ func (*InboundConnectionsConfig) Descriptor() ([]byte, []int) { return file_pbmesh_v2beta1_connection_proto_rawDescGZIP(), []int{1} } -func (x *InboundConnectionsConfig) GetMaxInboundConnections() uint64 { +func (x *InboundConnectionsConfig) GetMaxInboundConnections() uint32 { if x != nil { return x.MaxInboundConnections } @@ -209,11 +209,11 @@ var file_pbmesh_v2beta1_connection_proto_rawDesc = []byte{ 0x0a, 0x18, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x36, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x04, 0x52, 0x15, 0x6d, 0x61, 0x78, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x6d, 0x61, 0x78, 0x49, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x71, 0x0a, 0x1b, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x31, 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, 0x2e, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, 0x62, 0x61, 0x6c, 0x61, diff --git a/proto-public/pbmesh/v2beta1/connection.proto b/proto-public/pbmesh/v2beta1/connection.proto index fdb7217a123b..65cb21e586dd 100644 --- a/proto-public/pbmesh/v2beta1/connection.proto +++ b/proto-public/pbmesh/v2beta1/connection.proto @@ -17,8 +17,8 @@ message ConnectionConfig { // Referenced by ProxyConfiguration message InboundConnectionsConfig { - uint64 max_inbound_connections = 12; - BalanceConnections balance_inbound_connections = 13; + uint32 max_inbound_connections = 1; + BalanceConnections balance_inbound_connections = 2; } // +kubebuilder:validation:Enum=BALANCE_CONNECTIONS_DEFAULT;BALANCE_CONNECTIONS_EXACT diff --git a/proto-public/pbmesh/v2beta1/connection_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/connection_deepcopy.gen.go index 97666ed9eb4c..a0cfa7775756 100644 --- a/proto-public/pbmesh/v2beta1/connection_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/connection_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ConnectionConfig within kubernetes types, where deepcopy-gen is used. func (in *ConnectionConfig) DeepCopyInto(out *ConnectionConfig) { - p := proto.Clone(in).(*ConnectionConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionConfig. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *ConnectionConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using InboundConnectionsConfig within kubernetes types, where deepcopy-gen is used. func (in *InboundConnectionsConfig) DeepCopyInto(out *InboundConnectionsConfig) { - p := proto.Clone(in).(*InboundConnectionsConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InboundConnectionsConfig. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/destination_policy_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/destination_policy_deepcopy.gen.go index 5ac5542a54bf..1935359729e5 100644 --- a/proto-public/pbmesh/v2beta1/destination_policy_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/destination_policy_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using DestinationPolicy within kubernetes types, where deepcopy-gen is used. func (in *DestinationPolicy) DeepCopyInto(out *DestinationPolicy) { - p := proto.Clone(in).(*DestinationPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationPolicy. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *DestinationPolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using DestinationConfig within kubernetes types, where deepcopy-gen is used. func (in *DestinationConfig) DeepCopyInto(out *DestinationConfig) { - p := proto.Clone(in).(*DestinationConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfig. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *DestinationConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using LocalityPrioritization within kubernetes types, where deepcopy-gen is used. func (in *LocalityPrioritization) DeepCopyInto(out *LocalityPrioritization) { - p := proto.Clone(in).(*LocalityPrioritization) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LocalityPrioritization. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *LocalityPrioritization) DeepCopyInterface() interface{} { // DeepCopyInto supports using LoadBalancer within kubernetes types, where deepcopy-gen is used. func (in *LoadBalancer) DeepCopyInto(out *LoadBalancer) { - p := proto.Clone(in).(*LoadBalancer) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancer. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *LoadBalancer) DeepCopyInterface() interface{} { // DeepCopyInto supports using RingHashConfig within kubernetes types, where deepcopy-gen is used. func (in *RingHashConfig) DeepCopyInto(out *RingHashConfig) { - p := proto.Clone(in).(*RingHashConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RingHashConfig. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *RingHashConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using LeastRequestConfig within kubernetes types, where deepcopy-gen is used. func (in *LeastRequestConfig) DeepCopyInto(out *LeastRequestConfig) { - p := proto.Clone(in).(*LeastRequestConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeastRequestConfig. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *LeastRequestConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using HashPolicy within kubernetes types, where deepcopy-gen is used. func (in *HashPolicy) DeepCopyInto(out *HashPolicy) { - p := proto.Clone(in).(*HashPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HashPolicy. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *HashPolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using CookieConfig within kubernetes types, where deepcopy-gen is used. func (in *CookieConfig) DeepCopyInto(out *CookieConfig) { - p := proto.Clone(in).(*CookieConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookieConfig. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/destinations_configuration_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/destinations_configuration_deepcopy.gen.go index d1413cc89df1..1c7f04e7f23a 100644 --- a/proto-public/pbmesh/v2beta1/destinations_configuration_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/destinations_configuration_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using DestinationsConfiguration within kubernetes types, where deepcopy-gen is used. func (in *DestinationsConfiguration) DeepCopyInto(out *DestinationsConfiguration) { - p := proto.Clone(in).(*DestinationsConfiguration) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationsConfiguration. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *DestinationsConfiguration) DeepCopyInterface() interface{} { // DeepCopyInto supports using DestinationConfigOverrides within kubernetes types, where deepcopy-gen is used. func (in *DestinationConfigOverrides) DeepCopyInto(out *DestinationConfigOverrides) { - p := proto.Clone(in).(*DestinationConfigOverrides) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfigOverrides. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *DestinationConfigOverrides) DeepCopyInterface() interface{} { // DeepCopyInto supports using DestinationConfiguration within kubernetes types, where deepcopy-gen is used. func (in *DestinationConfiguration) DeepCopyInto(out *DestinationConfiguration) { - p := proto.Clone(in).(*DestinationConfiguration) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfiguration. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *DestinationConfiguration) DeepCopyInterface() interface{} { // DeepCopyInto supports using DestinationLimits within kubernetes types, where deepcopy-gen is used. func (in *DestinationLimits) DeepCopyInto(out *DestinationLimits) { - p := proto.Clone(in).(*DestinationLimits) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationLimits. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *DestinationLimits) DeepCopyInterface() interface{} { // DeepCopyInto supports using PassiveHealthCheck within kubernetes types, where deepcopy-gen is used. func (in *PassiveHealthCheck) DeepCopyInto(out *PassiveHealthCheck) { - p := proto.Clone(in).(*PassiveHealthCheck) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PassiveHealthCheck. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/destinations_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/destinations_deepcopy.gen.go index ff04bf3fcf8b..3f513b7d861d 100644 --- a/proto-public/pbmesh/v2beta1/destinations_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/destinations_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Destinations within kubernetes types, where deepcopy-gen is used. func (in *Destinations) DeepCopyInto(out *Destinations) { - p := proto.Clone(in).(*Destinations) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Destinations. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Destinations) DeepCopyInterface() interface{} { // DeepCopyInto supports using Destination within kubernetes types, where deepcopy-gen is used. func (in *Destination) DeepCopyInto(out *Destination) { - p := proto.Clone(in).(*Destination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Destination. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *Destination) DeepCopyInterface() interface{} { // DeepCopyInto supports using IPPortAddress within kubernetes types, where deepcopy-gen is used. func (in *IPPortAddress) DeepCopyInto(out *IPPortAddress) { - p := proto.Clone(in).(*IPPortAddress) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IPPortAddress. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *IPPortAddress) DeepCopyInterface() interface{} { // DeepCopyInto supports using UnixSocketAddress within kubernetes types, where deepcopy-gen is used. func (in *UnixSocketAddress) DeepCopyInto(out *UnixSocketAddress) { - p := proto.Clone(in).(*UnixSocketAddress) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnixSocketAddress. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *UnixSocketAddress) DeepCopyInterface() interface{} { // DeepCopyInto supports using PreparedQueryDestination within kubernetes types, where deepcopy-gen is used. func (in *PreparedQueryDestination) DeepCopyInto(out *PreparedQueryDestination) { - p := proto.Clone(in).(*PreparedQueryDestination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreparedQueryDestination. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/expose_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/expose_deepcopy.gen.go index e191d353bdcb..2b75adbbcd34 100644 --- a/proto-public/pbmesh/v2beta1/expose_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/expose_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ExposeConfig within kubernetes types, where deepcopy-gen is used. func (in *ExposeConfig) DeepCopyInto(out *ExposeConfig) { - p := proto.Clone(in).(*ExposeConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExposeConfig. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *ExposeConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using ExposePath within kubernetes types, where deepcopy-gen is used. func (in *ExposePath) DeepCopyInto(out *ExposePath) { - p := proto.Clone(in).(*ExposePath) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExposePath. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/grpc_route_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/grpc_route_deepcopy.gen.go index 18574bb8cc20..ea7e1dc8ed26 100644 --- a/proto-public/pbmesh/v2beta1/grpc_route_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/grpc_route_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using GRPCRoute within kubernetes types, where deepcopy-gen is used. func (in *GRPCRoute) DeepCopyInto(out *GRPCRoute) { - p := proto.Clone(in).(*GRPCRoute) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRoute. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *GRPCRoute) DeepCopyInterface() interface{} { // DeepCopyInto supports using GRPCRouteRule within kubernetes types, where deepcopy-gen is used. func (in *GRPCRouteRule) DeepCopyInto(out *GRPCRouteRule) { - p := proto.Clone(in).(*GRPCRouteRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteRule. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *GRPCRouteRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using GRPCRouteMatch within kubernetes types, where deepcopy-gen is used. func (in *GRPCRouteMatch) DeepCopyInto(out *GRPCRouteMatch) { - p := proto.Clone(in).(*GRPCRouteMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteMatch. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *GRPCRouteMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using GRPCMethodMatch within kubernetes types, where deepcopy-gen is used. func (in *GRPCMethodMatch) DeepCopyInto(out *GRPCMethodMatch) { - p := proto.Clone(in).(*GRPCMethodMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCMethodMatch. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *GRPCMethodMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using GRPCHeaderMatch within kubernetes types, where deepcopy-gen is used. func (in *GRPCHeaderMatch) DeepCopyInto(out *GRPCHeaderMatch) { - p := proto.Clone(in).(*GRPCHeaderMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCHeaderMatch. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *GRPCHeaderMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using GRPCRouteFilter within kubernetes types, where deepcopy-gen is used. func (in *GRPCRouteFilter) DeepCopyInto(out *GRPCRouteFilter) { - p := proto.Clone(in).(*GRPCRouteFilter) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCRouteFilter. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *GRPCRouteFilter) DeepCopyInterface() interface{} { // DeepCopyInto supports using GRPCBackendRef within kubernetes types, where deepcopy-gen is used. func (in *GRPCBackendRef) DeepCopyInto(out *GRPCBackendRef) { - p := proto.Clone(in).(*GRPCBackendRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GRPCBackendRef. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/http_route_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/http_route_deepcopy.gen.go index 222cb8361e03..6d339e5afde2 100644 --- a/proto-public/pbmesh/v2beta1/http_route_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/http_route_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using HTTPRoute within kubernetes types, where deepcopy-gen is used. func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) { - p := proto.Clone(in).(*HTTPRoute) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRoute. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *HTTPRoute) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPRouteRule within kubernetes types, where deepcopy-gen is used. func (in *HTTPRouteRule) DeepCopyInto(out *HTTPRouteRule) { - p := proto.Clone(in).(*HTTPRouteRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteRule. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *HTTPRouteRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPRouteMatch within kubernetes types, where deepcopy-gen is used. func (in *HTTPRouteMatch) DeepCopyInto(out *HTTPRouteMatch) { - p := proto.Clone(in).(*HTTPRouteMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteMatch. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *HTTPRouteMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPPathMatch within kubernetes types, where deepcopy-gen is used. func (in *HTTPPathMatch) DeepCopyInto(out *HTTPPathMatch) { - p := proto.Clone(in).(*HTTPPathMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPPathMatch. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *HTTPPathMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPHeaderMatch within kubernetes types, where deepcopy-gen is used. func (in *HTTPHeaderMatch) DeepCopyInto(out *HTTPHeaderMatch) { - p := proto.Clone(in).(*HTTPHeaderMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeaderMatch. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *HTTPHeaderMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPQueryParamMatch within kubernetes types, where deepcopy-gen is used. func (in *HTTPQueryParamMatch) DeepCopyInto(out *HTTPQueryParamMatch) { - p := proto.Clone(in).(*HTTPQueryParamMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPQueryParamMatch. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *HTTPQueryParamMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPRouteFilter within kubernetes types, where deepcopy-gen is used. func (in *HTTPRouteFilter) DeepCopyInto(out *HTTPRouteFilter) { - p := proto.Clone(in).(*HTTPRouteFilter) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteFilter. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *HTTPRouteFilter) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPHeaderFilter within kubernetes types, where deepcopy-gen is used. func (in *HTTPHeaderFilter) DeepCopyInto(out *HTTPHeaderFilter) { - p := proto.Clone(in).(*HTTPHeaderFilter) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeaderFilter. Required by controller-gen. @@ -175,8 +175,8 @@ func (in *HTTPHeaderFilter) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPHeader within kubernetes types, where deepcopy-gen is used. func (in *HTTPHeader) DeepCopyInto(out *HTTPHeader) { - p := proto.Clone(in).(*HTTPHeader) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeader. Required by controller-gen. @@ -196,8 +196,8 @@ func (in *HTTPHeader) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPURLRewriteFilter within kubernetes types, where deepcopy-gen is used. func (in *HTTPURLRewriteFilter) DeepCopyInto(out *HTTPURLRewriteFilter) { - p := proto.Clone(in).(*HTTPURLRewriteFilter) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPURLRewriteFilter. Required by controller-gen. @@ -217,8 +217,8 @@ func (in *HTTPURLRewriteFilter) DeepCopyInterface() interface{} { // DeepCopyInto supports using HTTPBackendRef within kubernetes types, where deepcopy-gen is used. func (in *HTTPBackendRef) DeepCopyInto(out *HTTPBackendRef) { - p := proto.Clone(in).(*HTTPBackendRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPBackendRef. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/http_route_retries_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/http_route_retries_deepcopy.gen.go index b523a58b77c1..abd2a515332d 100644 --- a/proto-public/pbmesh/v2beta1/http_route_retries_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/http_route_retries_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using HTTPRouteRetries within kubernetes types, where deepcopy-gen is used. func (in *HTTPRouteRetries) DeepCopyInto(out *HTTPRouteRetries) { - p := proto.Clone(in).(*HTTPRouteRetries) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteRetries. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/http_route_timeouts_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/http_route_timeouts_deepcopy.gen.go index ea92d9038d48..c131310e5e26 100644 --- a/proto-public/pbmesh/v2beta1/http_route_timeouts_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/http_route_timeouts_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using HTTPRouteTimeouts within kubernetes types, where deepcopy-gen is used. func (in *HTTPRouteTimeouts) DeepCopyInto(out *HTTPRouteTimeouts) { - p := proto.Clone(in).(*HTTPRouteTimeouts) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteTimeouts. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_deepcopy.gen.go index af2ac36c73ad..f4c5c96039d5 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/access_logs_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using AccessLogs within kubernetes types, where deepcopy-gen is used. func (in *AccessLogs) DeepCopyInto(out *AccessLogs) { - p := proto.Clone(in).(*AccessLogs) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessLogs. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/address_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/address_deepcopy.gen.go index 81cf39a4593a..b2700f704eff 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/address_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/address_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using HostPortAddress within kubernetes types, where deepcopy-gen is used. func (in *HostPortAddress) DeepCopyInto(out *HostPortAddress) { - p := proto.Clone(in).(*HostPortAddress) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostPortAddress. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *HostPortAddress) DeepCopyInterface() interface{} { // DeepCopyInto supports using UnixSocketAddress within kubernetes types, where deepcopy-gen is used. func (in *UnixSocketAddress) DeepCopyInto(out *UnixSocketAddress) { - p := proto.Clone(in).(*UnixSocketAddress) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnixSocketAddress. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.go index 81a0f3f97ee0..ba7386f527e0 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/cluster.pb.go @@ -93,7 +93,7 @@ type Cluster struct { // alt_stat_name is the name used for observability in place of cluster name if provided. AltStatName string `protobuf:"bytes,5,opt,name=alt_stat_name,json=altStatName,proto3" json:"alt_stat_name,omitempty"` // protocol is the local path protocol or the service protocol. - Protocol string `protobuf:"bytes,6,opt,name=protocol,proto3" json:"protocol,omitempty"` + Protocol Protocol `protobuf:"varint,6,opt,name=protocol,proto3,enum=hashicorp.consul.mesh.v2beta1.pbproxystate.Protocol" json:"protocol,omitempty"` } func (x *Cluster) Reset() { @@ -170,11 +170,11 @@ func (x *Cluster) GetAltStatName() string { return "" } -func (x *Cluster) GetProtocol() string { +func (x *Cluster) GetProtocol() Protocol { if x != nil { return x.Protocol } - return "" + return Protocol_PROTOCOL_UNSPECIFIED } type isCluster_Group interface { @@ -1768,114 +1768,93 @@ var file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDesc = []byte{ 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x75, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70, 0x62, 0x6d, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, - 0x72, 0x74, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, - 0xe9, 0x02, 0x0a, 0x07, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x62, 0x0a, 0x0e, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, - 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, + 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x2f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x73, + 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9f, 0x03, 0x0a, 0x07, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x62, 0x0a, 0x0e, 0x66, + 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x39, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, + 0x52, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, + 0x62, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x66, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x12, 0x62, 0x0a, 0x0e, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x39, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x39, 0x0a, 0x19, 0x65, 0x73, 0x63, 0x61, 0x70, - 0x65, 0x5f, 0x68, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, - 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x65, 0x73, 0x63, 0x61, - 0x70, 0x65, 0x48, 0x61, 0x74, 0x63, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x73, - 0x6f, 0x6e, 0x12, 0x22, 0x0a, 0x0d, 0x61, 0x6c, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x6c, 0x74, 0x53, 0x74, - 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, - 0x6f, 0x6c, 0x42, 0x07, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xcc, 0x01, 0x0a, 0x0d, - 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x62, 0x0a, - 0x0f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x52, 0x0e, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x73, 0x12, 0x57, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x3f, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x46, - 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x84, 0x01, 0x0a, 0x13, 0x46, - 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x74, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x75, - 0x73, 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x42, 0x0a, - 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, - 0x74, 0x22, 0xa1, 0x03, 0x0a, 0x0d, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x5c, 0x0a, 0x07, 0x64, 0x79, 0x6e, 0x61, 0x6d, - 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x48, 0x00, 0x52, 0x0d, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x12, 0x39, 0x0a, 0x19, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x5f, 0x68, 0x61, + 0x74, 0x63, 0x68, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x48, 0x61, + 0x74, 0x63, 0x68, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x22, + 0x0a, 0x0d, 0x61, 0x6c, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x42, 0x07, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xcc, 0x01, + 0x0a, 0x0d, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, + 0x62, 0x0a, 0x0f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x5f, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, 0x6e, 0x64, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x07, 0x64, 0x79, - 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x12, 0x59, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, - 0x12, 0x50, 0x0a, 0x03, 0x64, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 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, 0x2e, 0x70, 0x62, - 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x4e, 0x53, 0x45, 0x6e, - 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x03, 0x64, - 0x6e, 0x73, 0x12, 0x68, 0x0a, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, - 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x52, 0x0e, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, + 0x75, 0x70, 0x73, 0x12, 0x57, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x3f, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x84, 0x01, 0x0a, + 0x13, 0x46, 0x61, 0x69, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x74, 0x5f, + 0x73, 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0e, 0x75, 0x73, 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x42, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x22, 0xa1, 0x03, 0x0a, 0x0d, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x5c, 0x0a, 0x07, 0x64, 0x79, 0x6e, + 0x61, 0x6d, 0x69, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, + 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x07, + 0x64, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x12, 0x59, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x69, + 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3f, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x63, 0x12, 0x50, 0x0a, 0x03, 0x64, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x3c, 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, 0x2e, + 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, 0x00, 0x52, - 0x0b, 0x70, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x42, 0x07, 0x0a, 0x05, - 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xd6, 0x01, 0x0a, 0x14, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, - 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5e, - 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x46, - 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, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x79, 0x6e, 0x61, + 0x03, 0x64, 0x6e, 0x73, 0x12, 0x68, 0x0a, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, + 0x75, 0x67, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x44, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, + 0x67, 0x68, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x48, + 0x00, 0x52, 0x0b, 0x70, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x42, 0x07, + 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xd6, 0x01, 0x0a, 0x14, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5e, - 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x65, - 0x74, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x6c, 0x73, 0x22, 0xde, - 0x01, 0x0a, 0x18, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x45, 0x6e, - 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x62, 0x0a, 0x06, 0x63, - 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4a, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, - 0x6f, 0x75, 0x67, 0x68, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, - 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, - 0x5e, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, 0x73, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, - 0x65, 0x74, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x6c, 0x73, 0x22, - 0xce, 0x01, 0x0a, 0x10, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, - 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5a, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x2e, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, + 0x12, 0x5e, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x46, 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, + 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x79, + 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x5e, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, @@ -1883,286 +1862,313 @@ var file_pbmesh_v2beta1_pbproxystate_cluster_proto_rawDesc = []byte{ 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x6c, 0x73, - 0x22, 0x74, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5d, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, - 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x22, 0xde, 0x01, 0x0a, 0x18, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, + 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x62, 0x0a, + 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x4a, 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, 0x2e, 0x70, 0x62, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x61, 0x73, 0x73, 0x74, + 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, + 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x5e, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, 0x6c, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, - 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x28, 0x0a, 0x12, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0x7e, 0x0a, 0x16, 0x4c, 0x34, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x08, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 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, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x34, 0x57, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x22, 0x7e, 0x0a, 0x16, 0x4c, 0x37, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x43, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x08, 0x63, 0x6c, - 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, 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, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x37, 0x57, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, - 0x22, 0x68, 0x0a, 0x1c, 0x4c, 0x34, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, - 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xcf, 0x01, 0x0a, 0x1c, 0x4c, - 0x37, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x34, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x77, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x65, 0x0a, 0x10, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, - 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3a, 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, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x48, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x68, 0x65, 0x61, - 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x80, 0x08, 0x0a, - 0x1a, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, - 0x36, 0x0a, 0x17, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x6e, 0x69, 0x63, - 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x54, 0x68, - 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x67, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x73, 0x74, - 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x40, - 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, 0x2e, 0x70, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x48, 0x00, 0x52, 0x0c, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x61, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x6f, 0x62, 0x69, 0x6e, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x6f, 0x75, 0x6e, 0x64, - 0x52, 0x6f, 0x62, 0x69, 0x6e, 0x48, 0x00, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, - 0x62, 0x69, 0x6e, 0x12, 0x54, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x3a, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x48, - 0x00, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x5b, 0x0a, 0x09, 0x72, 0x69, 0x6e, - 0x67, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 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, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x52, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x48, 0x00, 0x52, 0x08, 0x72, 0x69, - 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x12, 0x54, 0x0a, 0x06, 0x6d, 0x61, 0x67, 0x6c, 0x65, 0x76, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x6f, + 0x63, 0x6b, 0x65, 0x74, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, 0x6c, + 0x73, 0x22, 0xce, 0x01, 0x0a, 0x10, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5a, 0x0a, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x42, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x61, 0x67, 0x6c, - 0x65, 0x76, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x61, 0x67, 0x6c, 0x65, 0x76, 0x12, 0x66, 0x0a, 0x10, - 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, - 0x65, 0x72, 0x73, 0x52, 0x0f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, - 0x6b, 0x65, 0x72, 0x73, 0x12, 0x69, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x5f, - 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x3c, 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, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x75, 0x74, - 0x6c, 0x69, 0x65, 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6f, - 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x85, 0x01, 0x0a, 0x1b, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x61, 0x74, 0x65, 0x2e, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, + 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x12, 0x5e, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x74, + 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x6f, 0x72, 0x74, 0x53, + 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x0b, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x54, + 0x6c, 0x73, 0x22, 0x74, 0x0a, 0x13, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, + 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x5d, 0x0a, 0x06, 0x63, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, + 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x52, 0x06, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x28, 0x0a, 0x12, 0x44, 0x65, 0x73, 0x74, + 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x22, 0x7e, 0x0a, 0x16, 0x4c, 0x34, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x08, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, + 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, 0x2e, 0x70, + 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x34, 0x57, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x73, 0x22, 0x7e, 0x0a, 0x16, 0x4c, 0x37, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, + 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x64, 0x0a, 0x08, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x48, + 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, 0x2e, 0x70, + 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x37, 0x57, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x52, 0x08, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, + 0x72, 0x73, 0x22, 0x68, 0x0a, 0x1c, 0x4c, 0x34, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, + 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0xcf, 0x01, 0x0a, + 0x1c, 0x4c, 0x37, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x44, 0x65, 0x73, 0x74, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x34, 0x0a, 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x06, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x65, 0x0a, 0x10, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x5f, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x3a, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x4d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x80, + 0x08, 0x0a, 0x1a, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, + 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, + 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x12, 0x36, 0x0a, 0x17, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x6e, + 0x69, 0x63, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x6e, 0x69, 0x63, + 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x67, 0x0a, 0x0d, 0x6c, 0x65, 0x61, + 0x73, 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x40, 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, + 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x48, 0x00, 0x52, 0x0c, 0x6c, 0x65, 0x61, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x61, 0x0a, 0x0b, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x6f, 0x62, 0x69, + 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3e, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x6f, 0x75, + 0x6e, 0x64, 0x52, 0x6f, 0x62, 0x69, 0x6e, 0x48, 0x00, 0x52, 0x0a, 0x72, 0x6f, 0x75, 0x6e, 0x64, + 0x52, 0x6f, 0x62, 0x69, 0x6e, 0x12, 0x54, 0x0a, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, 0x75, 0x70, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x5f, 0x61, - 0x6c, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, - 0x6d, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6c, 0x62, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x22, - 0x57, 0x0a, 0x14, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4c, 0x65, 0x61, 0x73, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0c, 0x63, 0x68, 0x6f, 0x69, 0x63, - 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x63, 0x68, 0x6f, - 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x42, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x62, 0x69, 0x6e, 0x22, 0x10, - 0x0a, 0x0e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x61, 0x6e, 0x64, 0x6f, 0x6d, - 0x22, 0xa6, 0x01, 0x0a, 0x10, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x69, 0x6e, - 0x67, 0x48, 0x61, 0x73, 0x68, 0x12, 0x48, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, - 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, - 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x12, - 0x48, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x5f, - 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, - 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, - 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x4c, 0x42, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x61, 0x67, 0x6c, 0x65, 0x76, 0x22, 0x76, 0x0a, 0x0f, 0x43, - 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x63, - 0x0a, 0x0f, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x61, 0x6e, 0x64, 0x6f, + 0x6d, 0x48, 0x00, 0x52, 0x06, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x12, 0x5b, 0x0a, 0x09, 0x72, + 0x69, 0x6e, 0x67, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, + 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, 0x2e, 0x70, + 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x52, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x48, 0x00, 0x52, 0x08, + 0x72, 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x12, 0x54, 0x0a, 0x06, 0x6d, 0x61, 0x67, 0x6c, + 0x65, 0x76, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x61, + 0x67, 0x6c, 0x65, 0x76, 0x48, 0x00, 0x52, 0x06, 0x6d, 0x61, 0x67, 0x6c, 0x65, 0x76, 0x12, 0x66, + 0x0a, 0x10, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x65, + 0x72, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, + 0x61, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, + 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x69, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, + 0x72, 0x5f, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x3c, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, + 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x10, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x85, 0x01, 0x0a, 0x1b, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x6d, - 0x69, 0x74, 0x73, 0x52, 0x0e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, 0x69, 0x6d, - 0x69, 0x74, 0x73, 0x22, 0xfd, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, + 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, + 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, + 0x5f, 0x61, 0x6c, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x75, 0x73, 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, + 0x4e, 0x61, 0x6d, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x6c, 0x62, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x22, 0x57, 0x0a, 0x14, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4c, 0x65, 0x61, + 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3f, 0x0a, 0x0c, 0x63, 0x68, 0x6f, + 0x69, 0x63, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x6d, - 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4e, 0x0a, - 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, + 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x63, + 0x68, 0x6f, 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x42, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x6f, 0x75, 0x6e, 0x64, 0x52, 0x6f, 0x62, 0x69, 0x6e, + 0x22, 0x10, 0x0a, 0x0e, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x61, 0x6e, 0x64, + 0x6f, 0x6d, 0x22, 0xa6, 0x01, 0x0a, 0x10, 0x4c, 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, + 0x69, 0x6e, 0x67, 0x48, 0x61, 0x73, 0x68, 0x12, 0x48, 0x0a, 0x11, 0x6d, 0x69, 0x6e, 0x69, 0x6d, + 0x75, 0x6d, 0x5f, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x0f, 0x6d, 0x69, 0x6e, 0x69, 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, + 0x65, 0x12, 0x48, 0x0a, 0x11, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x5f, 0x72, 0x69, 0x6e, + 0x67, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, + 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x6d, 0x61, 0x78, 0x69, + 0x6d, 0x75, 0x6d, 0x52, 0x69, 0x6e, 0x67, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x10, 0x0a, 0x0e, 0x4c, + 0x42, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4d, 0x61, 0x67, 0x6c, 0x65, 0x76, 0x22, 0x76, 0x0a, + 0x0f, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, + 0x12, 0x63, 0x0a, 0x0f, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3a, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, + 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x73, 0x52, 0x0e, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x4c, + 0x69, 0x6d, 0x69, 0x74, 0x73, 0x22, 0xfd, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x45, 0x0a, 0x0f, 0x6d, 0x61, 0x78, 0x5f, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x0e, 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x4e, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x70, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x6d, 0x61, 0x78, + 0x50, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, + 0x54, 0x0a, 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x15, + 0x6d, 0x61, 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x83, 0x03, 0x0a, 0x10, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, + 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, + 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, + 0x6c, 0x12, 0x45, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x35, 0x78, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, + 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, 0x78, 0x78, 0x12, 0x58, 0x0a, 0x19, 0x65, 0x6e, 0x66, 0x6f, + 0x72, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, + 0x65, 0x5f, 0x35, 0x78, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, - 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x6d, 0x61, 0x78, 0x50, 0x65, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x54, 0x0a, - 0x17, 0x6d, 0x61, 0x78, 0x5f, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x15, 0x6d, 0x61, - 0x78, 0x43, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x73, 0x22, 0x83, 0x03, 0x0a, 0x10, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x44, - 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, - 0x45, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x35, - 0x78, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, - 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, - 0x69, 0x76, 0x65, 0x35, 0x78, 0x78, 0x12, 0x58, 0x0a, 0x19, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, - 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x35, 0x78, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, - 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x17, 0x65, 0x6e, 0x66, 0x6f, 0x72, 0x63, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, 0x78, 0x78, - 0x12, 0x4e, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x17, 0x65, 0x6e, 0x66, 0x6f, 0x72, + 0x63, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x74, 0x69, 0x76, 0x65, 0x35, + 0x78, 0x78, 0x12, 0x4e, 0x0a, 0x14, 0x6d, 0x61, 0x78, 0x5f, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, + 0x6d, 0x61, 0x78, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x63, 0x65, + 0x6e, 0x74, 0x12, 0x47, 0x0a, 0x12, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x65, 0x6a, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x6d, 0x61, - 0x78, 0x45, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, - 0x12, 0x47, 0x0a, 0x12, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x62, 0x61, 0x73, 0x65, 0x45, 0x6a, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x8b, 0x02, 0x0a, 0x19, 0x55, 0x70, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x74, 0x63, 0x70, 0x5f, 0x6b, - 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x10, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x54, - 0x69, 0x6d, 0x65, 0x12, 0x52, 0x0a, 0x16, 0x74, 0x63, 0x70, 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, - 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x14, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x4e, 0x0a, 0x14, 0x74, 0x63, 0x70, 0x5f, 0x6b, - 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x62, 0x61, 0x73, 0x65, 0x45, + 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x22, 0x8b, 0x02, 0x0a, 0x19, + 0x55, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x4a, 0x0a, 0x12, 0x74, 0x63, 0x70, + 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x12, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, - 0x65, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x1e, 0x50, 0x61, 0x73, 0x73, 0x74, - 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, - 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x63, - 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xfc, 0x04, - 0x0a, 0x16, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, - 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, - 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x63, 0x6f, - 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x36, 0x0a, 0x17, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x5f, 0x74, 0x68, - 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x15, 0x64, - 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x54, 0x68, 0x72, 0x65, 0x73, - 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x60, 0x0a, 0x0e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, 0x72, - 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, 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, 0x2e, 0x70, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, 0x65, - 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x66, 0x0a, 0x10, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, - 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x3b, 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, - 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, - 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x63, - 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x12, 0x69, - 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x44, 0x65, - 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, - 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x85, 0x01, 0x0a, 0x1b, 0x75, 0x70, - 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x45, 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, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, 0x70, 0x73, - 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x74, 0x5f, 0x73, 0x74, 0x61, - 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x75, 0x73, - 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc7, 0x01, 0x0a, - 0x19, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, + 0x6c, 0x75, 0x65, 0x52, 0x10, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, + 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x52, 0x0a, 0x16, 0x74, 0x63, 0x70, 0x5f, 0x6b, 0x65, 0x65, + 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x14, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, + 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x4e, 0x0a, 0x14, 0x74, 0x63, 0x70, + 0x5f, 0x6b, 0x65, 0x65, 0x70, 0x61, 0x6c, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x72, 0x6f, 0x62, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x12, 0x74, 0x63, 0x70, 0x4b, 0x65, 0x65, 0x70, 0x61, 0x6c, + 0x69, 0x76, 0x65, 0x50, 0x72, 0x6f, 0x62, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x1e, 0x50, 0x61, 0x73, + 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, + 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, + 0xfc, 0x04, 0x0a, 0x16, 0x44, 0x4e, 0x53, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, - 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x66, - 0x0a, 0x10, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x65, - 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, - 0x61, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, - 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x2a, 0x46, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x76, - 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x49, 0x53, 0x43, 0x4f, - 0x56, 0x45, 0x52, 0x59, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x47, 0x49, 0x43, 0x41, - 0x4c, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x59, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x10, 0x01, 0x42, 0xd2, - 0x02, 0x0a, 0x2e, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x42, 0x0c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, - 0x01, 0x5a, 0x44, 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, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, - 0x02, 0x2a, 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, 0x2e, - 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 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, 0x50, 0x62, 0x70, - 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 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, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0xea, 0x02, 0x2e, 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, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x36, + 0x0a, 0x17, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x70, 0x61, 0x6e, 0x69, 0x63, 0x5f, + 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x50, 0x61, 0x6e, 0x69, 0x63, 0x54, 0x68, 0x72, + 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x12, 0x60, 0x0a, 0x0e, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x39, + 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, 0x2e, 0x70, + 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0d, 0x64, 0x69, 0x73, 0x63, 0x6f, + 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x66, 0x0a, 0x10, 0x63, 0x69, 0x72, 0x63, + 0x75, 0x69, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, + 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x52, + 0x0f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, + 0x12, 0x69, 0x0a, 0x11, 0x6f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x74, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3c, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, + 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x4f, 0x75, 0x74, 0x6c, 0x69, 0x65, 0x72, + 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x10, 0x6f, 0x75, 0x74, 0x6c, 0x69, + 0x65, 0x72, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x85, 0x01, 0x0a, 0x1b, + 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x45, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x55, + 0x70, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x19, 0x75, 0x70, 0x73, 0x74, 0x72, 0x65, + 0x61, 0x6d, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x11, 0x75, 0x73, 0x65, 0x5f, 0x61, 0x6c, 0x74, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, + 0x75, 0x73, 0x65, 0x41, 0x6c, 0x74, 0x53, 0x74, 0x61, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xc7, + 0x01, 0x0a, 0x19, 0x53, 0x74, 0x61, 0x74, 0x69, 0x63, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, + 0x74, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x42, 0x0a, 0x0f, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0e, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, + 0x12, 0x66, 0x0a, 0x10, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x5f, 0x62, 0x72, 0x65, 0x61, + 0x6b, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x43, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, 0x42, + 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x52, 0x0f, 0x63, 0x69, 0x72, 0x63, 0x75, 0x69, 0x74, + 0x42, 0x72, 0x65, 0x61, 0x6b, 0x65, 0x72, 0x73, 0x2a, 0x46, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x79, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x44, 0x49, 0x53, + 0x43, 0x4f, 0x56, 0x45, 0x52, 0x59, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4c, 0x4f, 0x47, 0x49, + 0x43, 0x41, 0x4c, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x56, 0x45, + 0x52, 0x59, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x10, 0x01, + 0x42, 0xd2, 0x02, 0x0a, 0x2e, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x42, 0x0c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x44, 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, 0x2f, 0x70, 0x62, 0x70, + 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, + 0x50, 0xaa, 0x02, 0x2a, 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, 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, + 0x2a, 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, 0x50, + 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 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, 0x50, 0x62, 0x70, 0x72, + 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 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, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -2207,71 +2213,73 @@ var file_pbmesh_v2beta1_pbproxystate_cluster_proto_goTypes = []interface{}{ (*PassthroughEndpointGroupConfig)(nil), // 24: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroupConfig (*DNSEndpointGroupConfig)(nil), // 25: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig (*StaticEndpointGroupConfig)(nil), // 26: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig - (*durationpb.Duration)(nil), // 27: google.protobuf.Duration - (*TransportSocket)(nil), // 28: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - (*wrapperspb.UInt32Value)(nil), // 29: google.protobuf.UInt32Value - (*HeaderMutation)(nil), // 30: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation - (*wrapperspb.UInt64Value)(nil), // 31: google.protobuf.UInt64Value + (Protocol)(0), // 27: hashicorp.consul.mesh.v2beta1.pbproxystate.Protocol + (*durationpb.Duration)(nil), // 28: google.protobuf.Duration + (*TransportSocket)(nil), // 29: hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket + (*wrapperspb.UInt32Value)(nil), // 30: google.protobuf.UInt32Value + (*HeaderMutation)(nil), // 31: hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation + (*wrapperspb.UInt64Value)(nil), // 32: google.protobuf.UInt64Value } var file_pbmesh_v2beta1_pbproxystate_cluster_proto_depIdxs = []int32{ 2, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster.failover_group:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup 4, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster.endpoint_group:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup - 4, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup.endpoint_groups:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup - 3, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroupConfig - 27, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 5, // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.dynamic:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup - 8, // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.static:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroup - 7, // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.dns:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup - 6, // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.passthrough:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup - 14, // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig - 28, // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - 24, // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroupConfig - 28, // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - 25, // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig - 28, // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket - 26, // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig - 12, // 16: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedClusterGroup.clusters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedDestinationCluster - 13, // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedClusterGroup.clusters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster - 29, // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedDestinationCluster.weight:type_name -> google.protobuf.UInt32Value - 29, // 19: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster.weight:type_name -> google.protobuf.UInt32Value - 30, // 20: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster.header_mutations:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation - 27, // 21: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 15, // 22: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.least_request:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyLeastRequest - 16, // 23: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.round_robin:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRoundRobin - 17, // 24: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.random:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRandom - 18, // 25: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.ring_hash:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash - 19, // 26: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.maglev:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyMaglev - 20, // 27: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers - 22, // 28: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.outlier_detection:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection - 23, // 29: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.upstream_connection_options:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions - 29, // 30: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyLeastRequest.choice_count:type_name -> google.protobuf.UInt32Value - 31, // 31: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash.minimum_ring_size:type_name -> google.protobuf.UInt64Value - 31, // 32: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash.maximum_ring_size:type_name -> google.protobuf.UInt64Value - 21, // 33: hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers.upstream_limits:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits - 29, // 34: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_connections:type_name -> google.protobuf.UInt32Value - 29, // 35: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_pending_requests:type_name -> google.protobuf.UInt32Value - 29, // 36: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_concurrent_requests:type_name -> google.protobuf.UInt32Value - 27, // 37: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.interval:type_name -> google.protobuf.Duration - 29, // 38: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.consecutive_5xx:type_name -> google.protobuf.UInt32Value - 29, // 39: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.enforcing_consecutive_5xx:type_name -> google.protobuf.UInt32Value - 29, // 40: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.max_ejection_percent:type_name -> google.protobuf.UInt32Value - 27, // 41: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.base_ejection_time:type_name -> google.protobuf.Duration - 29, // 42: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_time:type_name -> google.protobuf.UInt32Value - 29, // 43: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_interval:type_name -> google.protobuf.UInt32Value - 29, // 44: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_probes:type_name -> google.protobuf.UInt32Value - 27, // 45: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 27, // 46: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 0, // 47: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.discovery_type:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DiscoveryType - 20, // 48: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers - 22, // 49: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.outlier_detection:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection - 23, // 50: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.upstream_connection_options:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions - 27, // 51: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration - 20, // 52: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers - 53, // [53:53] is the sub-list for method output_type - 53, // [53:53] is the sub-list for method input_type - 53, // [53:53] is the sub-list for extension type_name - 53, // [53:53] is the sub-list for extension extendee - 0, // [0:53] is the sub-list for field type_name + 27, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Cluster.protocol:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Protocol + 4, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup.endpoint_groups:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup + 3, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroupConfig + 28, // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.FailoverGroupConfig.connect_timeout:type_name -> google.protobuf.Duration + 5, // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.dynamic:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup + 8, // 7: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.static:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroup + 7, // 8: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.dns:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup + 6, // 9: hashicorp.consul.mesh.v2beta1.pbproxystate.EndpointGroup.passthrough:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup + 14, // 10: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig + 29, // 11: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket + 24, // 12: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroupConfig + 29, // 13: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket + 25, // 14: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig + 29, // 15: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroup.outbound_tls:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.TransportSocket + 26, // 16: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroup.config:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig + 12, // 17: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedClusterGroup.clusters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedDestinationCluster + 13, // 18: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedClusterGroup.clusters:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster + 30, // 19: hashicorp.consul.mesh.v2beta1.pbproxystate.L4WeightedDestinationCluster.weight:type_name -> google.protobuf.UInt32Value + 30, // 20: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster.weight:type_name -> google.protobuf.UInt32Value + 31, // 21: hashicorp.consul.mesh.v2beta1.pbproxystate.L7WeightedDestinationCluster.header_mutations:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.HeaderMutation + 28, // 22: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration + 15, // 23: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.least_request:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyLeastRequest + 16, // 24: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.round_robin:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRoundRobin + 17, // 25: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.random:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRandom + 18, // 26: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.ring_hash:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash + 19, // 27: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.maglev:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyMaglev + 20, // 28: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers + 22, // 29: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.outlier_detection:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection + 23, // 30: hashicorp.consul.mesh.v2beta1.pbproxystate.DynamicEndpointGroupConfig.upstream_connection_options:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions + 30, // 31: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyLeastRequest.choice_count:type_name -> google.protobuf.UInt32Value + 32, // 32: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash.minimum_ring_size:type_name -> google.protobuf.UInt64Value + 32, // 33: hashicorp.consul.mesh.v2beta1.pbproxystate.LBPolicyRingHash.maximum_ring_size:type_name -> google.protobuf.UInt64Value + 21, // 34: hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers.upstream_limits:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits + 30, // 35: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_connections:type_name -> google.protobuf.UInt32Value + 30, // 36: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_pending_requests:type_name -> google.protobuf.UInt32Value + 30, // 37: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamLimits.max_concurrent_requests:type_name -> google.protobuf.UInt32Value + 28, // 38: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.interval:type_name -> google.protobuf.Duration + 30, // 39: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.consecutive_5xx:type_name -> google.protobuf.UInt32Value + 30, // 40: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.enforcing_consecutive_5xx:type_name -> google.protobuf.UInt32Value + 30, // 41: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.max_ejection_percent:type_name -> google.protobuf.UInt32Value + 28, // 42: hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection.base_ejection_time:type_name -> google.protobuf.Duration + 30, // 43: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_time:type_name -> google.protobuf.UInt32Value + 30, // 44: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_interval:type_name -> google.protobuf.UInt32Value + 30, // 45: hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions.tcp_keepalive_probes:type_name -> google.protobuf.UInt32Value + 28, // 46: hashicorp.consul.mesh.v2beta1.pbproxystate.PassthroughEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration + 28, // 47: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration + 0, // 48: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.discovery_type:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DiscoveryType + 20, // 49: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers + 22, // 50: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.outlier_detection:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.OutlierDetection + 23, // 51: hashicorp.consul.mesh.v2beta1.pbproxystate.DNSEndpointGroupConfig.upstream_connection_options:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.UpstreamConnectionOptions + 28, // 52: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig.connect_timeout:type_name -> google.protobuf.Duration + 20, // 53: hashicorp.consul.mesh.v2beta1.pbproxystate.StaticEndpointGroupConfig.circuit_breakers:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.CircuitBreakers + 54, // [54:54] is the sub-list for method output_type + 54, // [54:54] is the sub-list for method input_type + 54, // [54:54] is the sub-list for extension type_name + 54, // [54:54] is the sub-list for extension extendee + 0, // [0:54] is the sub-list for field type_name } func init() { file_pbmesh_v2beta1_pbproxystate_cluster_proto_init() } @@ -2280,6 +2288,7 @@ func file_pbmesh_v2beta1_pbproxystate_cluster_proto_init() { return } file_pbmesh_v2beta1_pbproxystate_header_mutations_proto_init() + file_pbmesh_v2beta1_pbproxystate_protocol_proto_init() file_pbmesh_v2beta1_pbproxystate_transport_socket_proto_init() if !protoimpl.UnsafeEnabled { file_pbmesh_v2beta1_pbproxystate_cluster_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.proto b/proto-public/pbmesh/v2beta1/pbproxystate/cluster.proto index c72fccbb8539..a84a3755c99b 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/cluster.proto +++ b/proto-public/pbmesh/v2beta1/pbproxystate/cluster.proto @@ -8,6 +8,7 @@ package hashicorp.consul.mesh.v2beta1.pbproxystate; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; import "pbmesh/v2beta1/pbproxystate/header_mutations.proto"; +import "pbmesh/v2beta1/pbproxystate/protocol.proto"; import "pbmesh/v2beta1/pbproxystate/transport_socket.proto"; message Cluster { @@ -23,7 +24,7 @@ message Cluster { // alt_stat_name is the name used for observability in place of cluster name if provided. string alt_stat_name = 5; // protocol is the local path protocol or the service protocol. - string protocol = 6; + Protocol protocol = 6; } message FailoverGroup { diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/cluster_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/cluster_deepcopy.gen.go index f06ac976e13f..1818a349bd45 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/cluster_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/cluster_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Cluster within kubernetes types, where deepcopy-gen is used. func (in *Cluster) DeepCopyInto(out *Cluster) { - p := proto.Clone(in).(*Cluster) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Cluster) DeepCopyInterface() interface{} { // DeepCopyInto supports using FailoverGroup within kubernetes types, where deepcopy-gen is used. func (in *FailoverGroup) DeepCopyInto(out *FailoverGroup) { - p := proto.Clone(in).(*FailoverGroup) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverGroup. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *FailoverGroup) DeepCopyInterface() interface{} { // DeepCopyInto supports using FailoverGroupConfig within kubernetes types, where deepcopy-gen is used. func (in *FailoverGroupConfig) DeepCopyInto(out *FailoverGroupConfig) { - p := proto.Clone(in).(*FailoverGroupConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FailoverGroupConfig. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *FailoverGroupConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using EndpointGroup within kubernetes types, where deepcopy-gen is used. func (in *EndpointGroup) DeepCopyInto(out *EndpointGroup) { - p := proto.Clone(in).(*EndpointGroup) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointGroup. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *EndpointGroup) DeepCopyInterface() interface{} { // DeepCopyInto supports using DynamicEndpointGroup within kubernetes types, where deepcopy-gen is used. func (in *DynamicEndpointGroup) DeepCopyInto(out *DynamicEndpointGroup) { - p := proto.Clone(in).(*DynamicEndpointGroup) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicEndpointGroup. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *DynamicEndpointGroup) DeepCopyInterface() interface{} { // DeepCopyInto supports using PassthroughEndpointGroup within kubernetes types, where deepcopy-gen is used. func (in *PassthroughEndpointGroup) DeepCopyInto(out *PassthroughEndpointGroup) { - p := proto.Clone(in).(*PassthroughEndpointGroup) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PassthroughEndpointGroup. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *PassthroughEndpointGroup) DeepCopyInterface() interface{} { // DeepCopyInto supports using DNSEndpointGroup within kubernetes types, where deepcopy-gen is used. func (in *DNSEndpointGroup) DeepCopyInto(out *DNSEndpointGroup) { - p := proto.Clone(in).(*DNSEndpointGroup) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointGroup. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *DNSEndpointGroup) DeepCopyInterface() interface{} { // DeepCopyInto supports using StaticEndpointGroup within kubernetes types, where deepcopy-gen is used. func (in *StaticEndpointGroup) DeepCopyInto(out *StaticEndpointGroup) { - p := proto.Clone(in).(*StaticEndpointGroup) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StaticEndpointGroup. Required by controller-gen. @@ -175,8 +175,8 @@ func (in *StaticEndpointGroup) DeepCopyInterface() interface{} { // DeepCopyInto supports using DestinationCluster within kubernetes types, where deepcopy-gen is used. func (in *DestinationCluster) DeepCopyInto(out *DestinationCluster) { - p := proto.Clone(in).(*DestinationCluster) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationCluster. Required by controller-gen. @@ -196,8 +196,8 @@ func (in *DestinationCluster) DeepCopyInterface() interface{} { // DeepCopyInto supports using L4WeightedClusterGroup within kubernetes types, where deepcopy-gen is used. func (in *L4WeightedClusterGroup) DeepCopyInto(out *L4WeightedClusterGroup) { - p := proto.Clone(in).(*L4WeightedClusterGroup) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L4WeightedClusterGroup. Required by controller-gen. @@ -217,8 +217,8 @@ func (in *L4WeightedClusterGroup) DeepCopyInterface() interface{} { // DeepCopyInto supports using L7WeightedClusterGroup within kubernetes types, where deepcopy-gen is used. func (in *L7WeightedClusterGroup) DeepCopyInto(out *L7WeightedClusterGroup) { - p := proto.Clone(in).(*L7WeightedClusterGroup) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L7WeightedClusterGroup. Required by controller-gen. @@ -238,8 +238,8 @@ func (in *L7WeightedClusterGroup) DeepCopyInterface() interface{} { // DeepCopyInto supports using L4WeightedDestinationCluster within kubernetes types, where deepcopy-gen is used. func (in *L4WeightedDestinationCluster) DeepCopyInto(out *L4WeightedDestinationCluster) { - p := proto.Clone(in).(*L4WeightedDestinationCluster) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L4WeightedDestinationCluster. Required by controller-gen. @@ -259,8 +259,8 @@ func (in *L4WeightedDestinationCluster) DeepCopyInterface() interface{} { // DeepCopyInto supports using L7WeightedDestinationCluster within kubernetes types, where deepcopy-gen is used. func (in *L7WeightedDestinationCluster) DeepCopyInto(out *L7WeightedDestinationCluster) { - p := proto.Clone(in).(*L7WeightedDestinationCluster) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L7WeightedDestinationCluster. Required by controller-gen. @@ -280,8 +280,8 @@ func (in *L7WeightedDestinationCluster) DeepCopyInterface() interface{} { // DeepCopyInto supports using DynamicEndpointGroupConfig within kubernetes types, where deepcopy-gen is used. func (in *DynamicEndpointGroupConfig) DeepCopyInto(out *DynamicEndpointGroupConfig) { - p := proto.Clone(in).(*DynamicEndpointGroupConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicEndpointGroupConfig. Required by controller-gen. @@ -301,8 +301,8 @@ func (in *DynamicEndpointGroupConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using LBPolicyLeastRequest within kubernetes types, where deepcopy-gen is used. func (in *LBPolicyLeastRequest) DeepCopyInto(out *LBPolicyLeastRequest) { - p := proto.Clone(in).(*LBPolicyLeastRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyLeastRequest. Required by controller-gen. @@ -322,8 +322,8 @@ func (in *LBPolicyLeastRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using LBPolicyRoundRobin within kubernetes types, where deepcopy-gen is used. func (in *LBPolicyRoundRobin) DeepCopyInto(out *LBPolicyRoundRobin) { - p := proto.Clone(in).(*LBPolicyRoundRobin) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRoundRobin. Required by controller-gen. @@ -343,8 +343,8 @@ func (in *LBPolicyRoundRobin) DeepCopyInterface() interface{} { // DeepCopyInto supports using LBPolicyRandom within kubernetes types, where deepcopy-gen is used. func (in *LBPolicyRandom) DeepCopyInto(out *LBPolicyRandom) { - p := proto.Clone(in).(*LBPolicyRandom) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRandom. Required by controller-gen. @@ -364,8 +364,8 @@ func (in *LBPolicyRandom) DeepCopyInterface() interface{} { // DeepCopyInto supports using LBPolicyRingHash within kubernetes types, where deepcopy-gen is used. func (in *LBPolicyRingHash) DeepCopyInto(out *LBPolicyRingHash) { - p := proto.Clone(in).(*LBPolicyRingHash) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyRingHash. Required by controller-gen. @@ -385,8 +385,8 @@ func (in *LBPolicyRingHash) DeepCopyInterface() interface{} { // DeepCopyInto supports using LBPolicyMaglev within kubernetes types, where deepcopy-gen is used. func (in *LBPolicyMaglev) DeepCopyInto(out *LBPolicyMaglev) { - p := proto.Clone(in).(*LBPolicyMaglev) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LBPolicyMaglev. Required by controller-gen. @@ -406,8 +406,8 @@ func (in *LBPolicyMaglev) DeepCopyInterface() interface{} { // DeepCopyInto supports using CircuitBreakers within kubernetes types, where deepcopy-gen is used. func (in *CircuitBreakers) DeepCopyInto(out *CircuitBreakers) { - p := proto.Clone(in).(*CircuitBreakers) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CircuitBreakers. Required by controller-gen. @@ -427,8 +427,8 @@ func (in *CircuitBreakers) DeepCopyInterface() interface{} { // DeepCopyInto supports using UpstreamLimits within kubernetes types, where deepcopy-gen is used. func (in *UpstreamLimits) DeepCopyInto(out *UpstreamLimits) { - p := proto.Clone(in).(*UpstreamLimits) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamLimits. Required by controller-gen. @@ -448,8 +448,8 @@ func (in *UpstreamLimits) DeepCopyInterface() interface{} { // DeepCopyInto supports using OutlierDetection within kubernetes types, where deepcopy-gen is used. func (in *OutlierDetection) DeepCopyInto(out *OutlierDetection) { - p := proto.Clone(in).(*OutlierDetection) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OutlierDetection. Required by controller-gen. @@ -469,8 +469,8 @@ func (in *OutlierDetection) DeepCopyInterface() interface{} { // DeepCopyInto supports using UpstreamConnectionOptions within kubernetes types, where deepcopy-gen is used. func (in *UpstreamConnectionOptions) DeepCopyInto(out *UpstreamConnectionOptions) { - p := proto.Clone(in).(*UpstreamConnectionOptions) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UpstreamConnectionOptions. Required by controller-gen. @@ -490,8 +490,8 @@ func (in *UpstreamConnectionOptions) DeepCopyInterface() interface{} { // DeepCopyInto supports using PassthroughEndpointGroupConfig within kubernetes types, where deepcopy-gen is used. func (in *PassthroughEndpointGroupConfig) DeepCopyInto(out *PassthroughEndpointGroupConfig) { - p := proto.Clone(in).(*PassthroughEndpointGroupConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PassthroughEndpointGroupConfig. Required by controller-gen. @@ -511,8 +511,8 @@ func (in *PassthroughEndpointGroupConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using DNSEndpointGroupConfig within kubernetes types, where deepcopy-gen is used. func (in *DNSEndpointGroupConfig) DeepCopyInto(out *DNSEndpointGroupConfig) { - p := proto.Clone(in).(*DNSEndpointGroupConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSEndpointGroupConfig. Required by controller-gen. @@ -532,8 +532,8 @@ func (in *DNSEndpointGroupConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using StaticEndpointGroupConfig within kubernetes types, where deepcopy-gen is used. func (in *StaticEndpointGroupConfig) DeepCopyInto(out *StaticEndpointGroupConfig) { - p := proto.Clone(in).(*StaticEndpointGroupConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StaticEndpointGroupConfig. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_deepcopy.gen.go index 62efabc96394..eeb1daa5d23c 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/endpoints_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Endpoints within kubernetes types, where deepcopy-gen is used. func (in *Endpoints) DeepCopyInto(out *Endpoints) { - p := proto.Clone(in).(*Endpoints) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoints. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Endpoints) DeepCopyInterface() interface{} { // DeepCopyInto supports using Endpoint within kubernetes types, where deepcopy-gen is used. func (in *Endpoint) DeepCopyInto(out *Endpoint) { - p := proto.Clone(in).(*Endpoint) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_deepcopy.gen.go index fc5617f23494..41fcb73d4662 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/escape_hatches_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using EscapeHatches within kubernetes types, where deepcopy-gen is used. func (in *EscapeHatches) DeepCopyInto(out *EscapeHatches) { - p := proto.Clone(in).(*EscapeHatches) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscapeHatches. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_deepcopy.gen.go index 2b09b2759738..97a77c7fc402 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/header_mutations_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using HeaderMutation within kubernetes types, where deepcopy-gen is used. func (in *HeaderMutation) DeepCopyInto(out *HeaderMutation) { - p := proto.Clone(in).(*HeaderMutation) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMutation. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *HeaderMutation) DeepCopyInterface() interface{} { // DeepCopyInto supports using RequestHeaderAdd within kubernetes types, where deepcopy-gen is used. func (in *RequestHeaderAdd) DeepCopyInto(out *RequestHeaderAdd) { - p := proto.Clone(in).(*RequestHeaderAdd) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestHeaderAdd. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *RequestHeaderAdd) DeepCopyInterface() interface{} { // DeepCopyInto supports using RequestHeaderRemove within kubernetes types, where deepcopy-gen is used. func (in *RequestHeaderRemove) DeepCopyInto(out *RequestHeaderRemove) { - p := proto.Clone(in).(*RequestHeaderRemove) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestHeaderRemove. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *RequestHeaderRemove) DeepCopyInterface() interface{} { // DeepCopyInto supports using ResponseHeaderAdd within kubernetes types, where deepcopy-gen is used. func (in *ResponseHeaderAdd) DeepCopyInto(out *ResponseHeaderAdd) { - p := proto.Clone(in).(*ResponseHeaderAdd) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResponseHeaderAdd. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *ResponseHeaderAdd) DeepCopyInterface() interface{} { // DeepCopyInto supports using ResponseHeaderRemove within kubernetes types, where deepcopy-gen is used. func (in *ResponseHeaderRemove) DeepCopyInto(out *ResponseHeaderRemove) { - p := proto.Clone(in).(*ResponseHeaderRemove) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResponseHeaderRemove. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *ResponseHeaderRemove) DeepCopyInterface() interface{} { // DeepCopyInto supports using Header within kubernetes types, where deepcopy-gen is used. func (in *Header) DeepCopyInto(out *Header) { - p := proto.Clone(in).(*Header) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Header. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/listener_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/listener_deepcopy.gen.go index 7208735dbd64..c721f40cbb91 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/listener_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/listener_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Listener within kubernetes types, where deepcopy-gen is used. func (in *Listener) DeepCopyInto(out *Listener) { - p := proto.Clone(in).(*Listener) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Listener. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Listener) DeepCopyInterface() interface{} { // DeepCopyInto supports using Router within kubernetes types, where deepcopy-gen is used. func (in *Router) DeepCopyInto(out *Router) { - p := proto.Clone(in).(*Router) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Router. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *Router) DeepCopyInterface() interface{} { // DeepCopyInto supports using Match within kubernetes types, where deepcopy-gen is used. func (in *Match) DeepCopyInto(out *Match) { - p := proto.Clone(in).(*Match) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Match. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *Match) DeepCopyInterface() interface{} { // DeepCopyInto supports using CidrRange within kubernetes types, where deepcopy-gen is used. func (in *CidrRange) DeepCopyInto(out *CidrRange) { - p := proto.Clone(in).(*CidrRange) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CidrRange. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *CidrRange) DeepCopyInterface() interface{} { // DeepCopyInto supports using L4Destination within kubernetes types, where deepcopy-gen is used. func (in *L4Destination) DeepCopyInto(out *L4Destination) { - p := proto.Clone(in).(*L4Destination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L4Destination. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *L4Destination) DeepCopyInterface() interface{} { // DeepCopyInto supports using L7DestinationRoute within kubernetes types, where deepcopy-gen is used. func (in *L7DestinationRoute) DeepCopyInto(out *L7DestinationRoute) { - p := proto.Clone(in).(*L7DestinationRoute) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L7DestinationRoute. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *L7DestinationRoute) DeepCopyInterface() interface{} { // DeepCopyInto supports using L7Destination within kubernetes types, where deepcopy-gen is used. func (in *L7Destination) DeepCopyInto(out *L7Destination) { - p := proto.Clone(in).(*L7Destination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new L7Destination. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *L7Destination) DeepCopyInterface() interface{} { // DeepCopyInto supports using SNIDestination within kubernetes types, where deepcopy-gen is used. func (in *SNIDestination) DeepCopyInto(out *SNIDestination) { - p := proto.Clone(in).(*SNIDestination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SNIDestination. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/protocol.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/protocol.pb.go new file mode 100644 index 000000000000..a14cdf986de6 --- /dev/null +++ b/proto-public/pbmesh/v2beta1/pbproxystate/protocol.pb.go @@ -0,0 +1,175 @@ +// 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/pbproxystate/protocol.proto + +package pbproxystate + +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) +) + +// +kubebuilder:validation:Enum=PROTOCOL_UNSPECIFIED;PROTOCOL_TCP;PROTOCOL_HTTP;PROTOCOL_HTTP2;PROTOCOL_GRPC +// +kubebuilder:validation:Type=string +type Protocol int32 + +const ( + Protocol_PROTOCOL_UNSPECIFIED Protocol = 0 + Protocol_PROTOCOL_TCP Protocol = 1 + Protocol_PROTOCOL_HTTP Protocol = 2 + Protocol_PROTOCOL_HTTP2 Protocol = 3 + Protocol_PROTOCOL_GRPC Protocol = 4 + // Protocol Mesh indicates that this port can speak Consul's mTLS based mesh protocol. + Protocol_PROTOCOL_MESH Protocol = 5 +) + +// Enum value maps for Protocol. +var ( + Protocol_name = map[int32]string{ + 0: "PROTOCOL_UNSPECIFIED", + 1: "PROTOCOL_TCP", + 2: "PROTOCOL_HTTP", + 3: "PROTOCOL_HTTP2", + 4: "PROTOCOL_GRPC", + 5: "PROTOCOL_MESH", + } + Protocol_value = map[string]int32{ + "PROTOCOL_UNSPECIFIED": 0, + "PROTOCOL_TCP": 1, + "PROTOCOL_HTTP": 2, + "PROTOCOL_HTTP2": 3, + "PROTOCOL_GRPC": 4, + "PROTOCOL_MESH": 5, + } +) + +func (x Protocol) Enum() *Protocol { + p := new(Protocol) + *p = x + return p +} + +func (x Protocol) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (Protocol) Descriptor() protoreflect.EnumDescriptor { + return file_pbmesh_v2beta1_pbproxystate_protocol_proto_enumTypes[0].Descriptor() +} + +func (Protocol) Type() protoreflect.EnumType { + return &file_pbmesh_v2beta1_pbproxystate_protocol_proto_enumTypes[0] +} + +func (x Protocol) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use Protocol.Descriptor instead. +func (Protocol) EnumDescriptor() ([]byte, []int) { + return file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescGZIP(), []int{0} +} + +var File_pbmesh_v2beta1_pbproxystate_protocol_proto protoreflect.FileDescriptor + +var file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDesc = []byte{ + 0x0a, 0x2a, 0x70, 0x62, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x2a, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, + 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x83, 0x01, 0x0a, 0x08, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x18, 0x0a, 0x14, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, + 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, + 0x10, 0x0a, 0x0c, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x43, 0x50, 0x10, + 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x48, 0x54, + 0x54, 0x50, 0x10, 0x02, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, + 0x5f, 0x48, 0x54, 0x54, 0x50, 0x32, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x50, 0x52, 0x4f, 0x54, + 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x50, + 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x4d, 0x45, 0x53, 0x48, 0x10, 0x05, 0x42, 0xd3, + 0x02, 0x0a, 0x2e, 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, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x42, 0x0d, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x44, 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, 0x2f, 0x70, 0x62, 0x70, 0x72, + 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, + 0xaa, 0x02, 0x2a, 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, + 0x2e, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, + 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, 0x50, 0x62, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 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, 0x50, 0x62, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0xea, 0x02, 0x2e, 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, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescOnce sync.Once + file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescData = file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDesc +) + +func file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescGZIP() []byte { + file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescOnce.Do(func() { + file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescData = protoimpl.X.CompressGZIP(file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescData) + }) + return file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDescData +} + +var file_pbmesh_v2beta1_pbproxystate_protocol_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_pbmesh_v2beta1_pbproxystate_protocol_proto_goTypes = []interface{}{ + (Protocol)(0), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.Protocol +} +var file_pbmesh_v2beta1_pbproxystate_protocol_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_pbproxystate_protocol_proto_init() } +func file_pbmesh_v2beta1_pbproxystate_protocol_proto_init() { + if File_pbmesh_v2beta1_pbproxystate_protocol_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDesc, + NumEnums: 1, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_pbmesh_v2beta1_pbproxystate_protocol_proto_goTypes, + DependencyIndexes: file_pbmesh_v2beta1_pbproxystate_protocol_proto_depIdxs, + EnumInfos: file_pbmesh_v2beta1_pbproxystate_protocol_proto_enumTypes, + }.Build() + File_pbmesh_v2beta1_pbproxystate_protocol_proto = out.File + file_pbmesh_v2beta1_pbproxystate_protocol_proto_rawDesc = nil + file_pbmesh_v2beta1_pbproxystate_protocol_proto_goTypes = nil + file_pbmesh_v2beta1_pbproxystate_protocol_proto_depIdxs = nil +} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/protocol.proto b/proto-public/pbmesh/v2beta1/pbproxystate/protocol.proto new file mode 100644 index 000000000000..afe3ff17523e --- /dev/null +++ b/proto-public/pbmesh/v2beta1/pbproxystate/protocol.proto @@ -0,0 +1,19 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +syntax = "proto3"; + +package hashicorp.consul.mesh.v2beta1.pbproxystate; + +// +kubebuilder:validation:Enum=PROTOCOL_UNSPECIFIED;PROTOCOL_TCP;PROTOCOL_HTTP;PROTOCOL_HTTP2;PROTOCOL_GRPC +// +kubebuilder:validation:Type=string +enum Protocol { + PROTOCOL_UNSPECIFIED = 0; + PROTOCOL_TCP = 1; + PROTOCOL_HTTP = 2; + PROTOCOL_HTTP2 = 3; + PROTOCOL_GRPC = 4; + + // Protocol Mesh indicates that this port can speak Consul's mTLS based mesh protocol. + PROTOCOL_MESH = 5; +} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/protocol_test.go b/proto-public/pbmesh/v2beta1/pbproxystate/protocol_test.go new file mode 100644 index 000000000000..683f84452f13 --- /dev/null +++ b/proto-public/pbmesh/v2beta1/pbproxystate/protocol_test.go @@ -0,0 +1,19 @@ +package pbproxystate + +import ( + "testing" + + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/stretchr/testify/require" +) + +// TestMirrorsCatalogProtocol ensures that there is no unintended drift between pbcatalog.Protocol and +// pbproxystate.Protocol. +func TestMirrorsCatalogProtocol(t *testing.T) { + require.Equal(t, pbcatalog.Protocol_value, Protocol_value, "pbcatalog.Protocol and pbproxystate.Protocol have diverged") + for i := range pbcatalog.Protocol_name { + require.Equal(t, pbcatalog.Protocol_name[i], Protocol_name[i], + "pbcatalog.Protocol and pbproxystate.Protocol ordinals do not match;"+ + " ordinals for equivalent values must match so that casting between them produces expected results") + } +} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/references_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/references_deepcopy.gen.go index c52d23730cf9..2cbe25a91750 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/references_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/references_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using LeafCertificateRef within kubernetes types, where deepcopy-gen is used. func (in *LeafCertificateRef) DeepCopyInto(out *LeafCertificateRef) { - p := proto.Clone(in).(*LeafCertificateRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeafCertificateRef. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *LeafCertificateRef) DeepCopyInterface() interface{} { // DeepCopyInto supports using TrustBundleRef within kubernetes types, where deepcopy-gen is used. func (in *TrustBundleRef) DeepCopyInto(out *TrustBundleRef) { - p := proto.Clone(in).(*TrustBundleRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrustBundleRef. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *TrustBundleRef) DeepCopyInterface() interface{} { // DeepCopyInto supports using EndpointRef within kubernetes types, where deepcopy-gen is used. func (in *EndpointRef) DeepCopyInto(out *EndpointRef) { - p := proto.Clone(in).(*EndpointRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointRef. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/route_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/route_deepcopy.gen.go index 2d2e71009410..e2eea4e78b5e 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/route_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/route_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Route within kubernetes types, where deepcopy-gen is used. func (in *Route) DeepCopyInto(out *Route) { - p := proto.Clone(in).(*Route) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Route) DeepCopyInterface() interface{} { // DeepCopyInto supports using VirtualHost within kubernetes types, where deepcopy-gen is used. func (in *VirtualHost) DeepCopyInto(out *VirtualHost) { - p := proto.Clone(in).(*VirtualHost) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualHost. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *VirtualHost) DeepCopyInterface() interface{} { // DeepCopyInto supports using RouteRule within kubernetes types, where deepcopy-gen is used. func (in *RouteRule) DeepCopyInto(out *RouteRule) { - p := proto.Clone(in).(*RouteRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteRule. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *RouteRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using RouteMatch within kubernetes types, where deepcopy-gen is used. func (in *RouteMatch) DeepCopyInto(out *RouteMatch) { - p := proto.Clone(in).(*RouteMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteMatch. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *RouteMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using PathMatch within kubernetes types, where deepcopy-gen is used. func (in *PathMatch) DeepCopyInto(out *PathMatch) { - p := proto.Clone(in).(*PathMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PathMatch. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *PathMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using QueryParameterMatch within kubernetes types, where deepcopy-gen is used. func (in *QueryParameterMatch) DeepCopyInto(out *QueryParameterMatch) { - p := proto.Clone(in).(*QueryParameterMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryParameterMatch. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *QueryParameterMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using HeaderMatch within kubernetes types, where deepcopy-gen is used. func (in *HeaderMatch) DeepCopyInto(out *HeaderMatch) { - p := proto.Clone(in).(*HeaderMatch) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderMatch. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *HeaderMatch) DeepCopyInterface() interface{} { // DeepCopyInto supports using RouteDestination within kubernetes types, where deepcopy-gen is used. func (in *RouteDestination) DeepCopyInto(out *RouteDestination) { - p := proto.Clone(in).(*RouteDestination) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteDestination. Required by controller-gen. @@ -175,8 +175,8 @@ func (in *RouteDestination) DeepCopyInterface() interface{} { // DeepCopyInto supports using DestinationConfiguration within kubernetes types, where deepcopy-gen is used. func (in *DestinationConfiguration) DeepCopyInto(out *DestinationConfiguration) { - p := proto.Clone(in).(*DestinationConfiguration) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationConfiguration. Required by controller-gen. @@ -196,8 +196,8 @@ func (in *DestinationConfiguration) DeepCopyInterface() interface{} { // DeepCopyInto supports using RetryPolicy within kubernetes types, where deepcopy-gen is used. func (in *RetryPolicy) DeepCopyInto(out *RetryPolicy) { - p := proto.Clone(in).(*RetryPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RetryPolicy. Required by controller-gen. @@ -217,8 +217,8 @@ func (in *RetryPolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using TimeoutConfig within kubernetes types, where deepcopy-gen is used. func (in *TimeoutConfig) DeepCopyInto(out *TimeoutConfig) { - p := proto.Clone(in).(*TimeoutConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TimeoutConfig. Required by controller-gen. @@ -238,8 +238,8 @@ func (in *TimeoutConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using LoadBalancerHashPolicy within kubernetes types, where deepcopy-gen is used. func (in *LoadBalancerHashPolicy) DeepCopyInto(out *LoadBalancerHashPolicy) { - p := proto.Clone(in).(*LoadBalancerHashPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancerHashPolicy. Required by controller-gen. @@ -259,8 +259,8 @@ func (in *LoadBalancerHashPolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using CookiePolicy within kubernetes types, where deepcopy-gen is used. func (in *CookiePolicy) DeepCopyInto(out *CookiePolicy) { - p := proto.Clone(in).(*CookiePolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CookiePolicy. Required by controller-gen. @@ -280,8 +280,8 @@ func (in *CookiePolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using HeaderPolicy within kubernetes types, where deepcopy-gen is used. func (in *HeaderPolicy) DeepCopyInto(out *HeaderPolicy) { - p := proto.Clone(in).(*HeaderPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HeaderPolicy. Required by controller-gen. @@ -301,8 +301,8 @@ func (in *HeaderPolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using QueryParameterPolicy within kubernetes types, where deepcopy-gen is used. func (in *QueryParameterPolicy) DeepCopyInto(out *QueryParameterPolicy) { - p := proto.Clone(in).(*QueryParameterPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new QueryParameterPolicy. Required by controller-gen. @@ -322,8 +322,8 @@ func (in *QueryParameterPolicy) DeepCopyInterface() interface{} { // DeepCopyInto supports using ConnectionPropertiesPolicy within kubernetes types, where deepcopy-gen is used. func (in *ConnectionPropertiesPolicy) DeepCopyInto(out *ConnectionPropertiesPolicy) { - p := proto.Clone(in).(*ConnectionPropertiesPolicy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConnectionPropertiesPolicy. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go index 316c185dfa34..b45d2a79261a 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using TrafficPermissions within kubernetes types, where deepcopy-gen is used. func (in *TrafficPermissions) DeepCopyInto(out *TrafficPermissions) { - p := proto.Clone(in).(*TrafficPermissions) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrafficPermissions. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *TrafficPermissions) DeepCopyInterface() interface{} { // DeepCopyInto supports using Permission within kubernetes types, where deepcopy-gen is used. func (in *Permission) DeepCopyInto(out *Permission) { - p := proto.Clone(in).(*Permission) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Permission. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *Permission) DeepCopyInterface() interface{} { // DeepCopyInto supports using Principal within kubernetes types, where deepcopy-gen is used. func (in *Principal) DeepCopyInto(out *Principal) { - p := proto.Clone(in).(*Principal) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Principal. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *Principal) DeepCopyInterface() interface{} { // DeepCopyInto supports using Spiffe within kubernetes types, where deepcopy-gen is used. func (in *Spiffe) DeepCopyInto(out *Spiffe) { - p := proto.Clone(in).(*Spiffe) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Spiffe. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_deepcopy.gen.go index f2ba600e77e4..0d0520e328b5 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/transport_socket_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using TLS within kubernetes types, where deepcopy-gen is used. func (in *TLS) DeepCopyInto(out *TLS) { - p := proto.Clone(in).(*TLS) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLS. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *TLS) DeepCopyInterface() interface{} { // DeepCopyInto supports using TransportSocket within kubernetes types, where deepcopy-gen is used. func (in *TransportSocket) DeepCopyInto(out *TransportSocket) { - p := proto.Clone(in).(*TransportSocket) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransportSocket. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *TransportSocket) DeepCopyInterface() interface{} { // DeepCopyInto supports using InboundMeshMTLS within kubernetes types, where deepcopy-gen is used. func (in *InboundMeshMTLS) DeepCopyInto(out *InboundMeshMTLS) { - p := proto.Clone(in).(*InboundMeshMTLS) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InboundMeshMTLS. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *InboundMeshMTLS) DeepCopyInterface() interface{} { // DeepCopyInto supports using OutboundMeshMTLS within kubernetes types, where deepcopy-gen is used. func (in *OutboundMeshMTLS) DeepCopyInto(out *OutboundMeshMTLS) { - p := proto.Clone(in).(*OutboundMeshMTLS) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OutboundMeshMTLS. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *OutboundMeshMTLS) DeepCopyInterface() interface{} { // DeepCopyInto supports using InboundNonMeshTLS within kubernetes types, where deepcopy-gen is used. func (in *InboundNonMeshTLS) DeepCopyInto(out *InboundNonMeshTLS) { - p := proto.Clone(in).(*InboundNonMeshTLS) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InboundNonMeshTLS. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *InboundNonMeshTLS) DeepCopyInterface() interface{} { // DeepCopyInto supports using OutboundNonMeshTLS within kubernetes types, where deepcopy-gen is used. func (in *OutboundNonMeshTLS) DeepCopyInto(out *OutboundNonMeshTLS) { - p := proto.Clone(in).(*OutboundNonMeshTLS) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OutboundNonMeshTLS. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *OutboundNonMeshTLS) DeepCopyInterface() interface{} { // DeepCopyInto supports using MeshInboundValidationContext within kubernetes types, where deepcopy-gen is used. func (in *MeshInboundValidationContext) DeepCopyInto(out *MeshInboundValidationContext) { - p := proto.Clone(in).(*MeshInboundValidationContext) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshInboundValidationContext. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *MeshInboundValidationContext) DeepCopyInterface() interface{} { // DeepCopyInto supports using MeshOutboundValidationContext within kubernetes types, where deepcopy-gen is used. func (in *MeshOutboundValidationContext) DeepCopyInto(out *MeshOutboundValidationContext) { - p := proto.Clone(in).(*MeshOutboundValidationContext) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MeshOutboundValidationContext. Required by controller-gen. @@ -175,8 +175,8 @@ func (in *MeshOutboundValidationContext) DeepCopyInterface() interface{} { // DeepCopyInto supports using NonMeshOutboundValidationContext within kubernetes types, where deepcopy-gen is used. func (in *NonMeshOutboundValidationContext) DeepCopyInto(out *NonMeshOutboundValidationContext) { - p := proto.Clone(in).(*NonMeshOutboundValidationContext) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NonMeshOutboundValidationContext. Required by controller-gen. @@ -196,8 +196,8 @@ func (in *NonMeshOutboundValidationContext) DeepCopyInterface() interface{} { // DeepCopyInto supports using SDSCertificate within kubernetes types, where deepcopy-gen is used. func (in *SDSCertificate) DeepCopyInto(out *SDSCertificate) { - p := proto.Clone(in).(*SDSCertificate) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SDSCertificate. Required by controller-gen. @@ -217,8 +217,8 @@ func (in *SDSCertificate) DeepCopyInterface() interface{} { // DeepCopyInto supports using TLSParameters within kubernetes types, where deepcopy-gen is used. func (in *TLSParameters) DeepCopyInto(out *TLSParameters) { - p := proto.Clone(in).(*TLSParameters) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLSParameters. Required by controller-gen. @@ -238,8 +238,8 @@ func (in *TLSParameters) DeepCopyInterface() interface{} { // DeepCopyInto supports using LeafCertificate within kubernetes types, where deepcopy-gen is used. func (in *LeafCertificate) DeepCopyInto(out *LeafCertificate) { - p := proto.Clone(in).(*LeafCertificate) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LeafCertificate. Required by controller-gen. @@ -259,8 +259,8 @@ func (in *LeafCertificate) DeepCopyInterface() interface{} { // DeepCopyInto supports using TrustBundle within kubernetes types, where deepcopy-gen is used. func (in *TrustBundle) DeepCopyInto(out *TrustBundle) { - p := proto.Clone(in).(*TrustBundle) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TrustBundle. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration.pb.go b/proto-public/pbmesh/v2beta1/proxy_configuration.pb.go index 1b09926b796f..a374848fd20e 100644 --- a/proto-public/pbmesh/v2beta1/proxy_configuration.pb.go +++ b/proto-public/pbmesh/v2beta1/proxy_configuration.pb.go @@ -298,20 +298,19 @@ type DynamicConfig struct { ExposeConfig *ExposeConfig `protobuf:"bytes,7,opt,name=expose_config,json=exposeConfig,proto3" json:"expose_config,omitempty"` // AccessLogs configures the output and format of Envoy access logs AccessLogs *AccessLogsConfig `protobuf:"bytes,8,opt,name=access_logs,json=accessLogs,proto3" json:"access_logs,omitempty"` - EnvoyExtensions []*EnvoyExtension `protobuf:"bytes,9,rep,name=envoy_extensions,json=envoyExtensions,proto3" json:"envoy_extensions,omitempty"` - PublicListenerJson string `protobuf:"bytes,10,opt,name=public_listener_json,json=publicListenerJson,proto3" json:"public_listener_json,omitempty"` - ListenerTracingJson string `protobuf:"bytes,11,opt,name=listener_tracing_json,json=listenerTracingJson,proto3" json:"listener_tracing_json,omitempty"` - LocalClusterJson string `protobuf:"bytes,12,opt,name=local_cluster_json,json=localClusterJson,proto3" json:"local_cluster_json,omitempty"` + PublicListenerJson string `protobuf:"bytes,9,opt,name=public_listener_json,json=publicListenerJson,proto3" json:"public_listener_json,omitempty"` + ListenerTracingJson string `protobuf:"bytes,10,opt,name=listener_tracing_json,json=listenerTracingJson,proto3" json:"listener_tracing_json,omitempty"` + LocalClusterJson string `protobuf:"bytes,11,opt,name=local_cluster_json,json=localClusterJson,proto3" json:"local_cluster_json,omitempty"` // deprecated: // local_workload_address, local_workload_port, and local_workload_socket_path // are deprecated and are only needed for migration of existing resources. // // Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. - LocalWorkloadAddress string `protobuf:"bytes,13,opt,name=local_workload_address,json=localWorkloadAddress,proto3" json:"local_workload_address,omitempty"` + LocalWorkloadAddress string `protobuf:"bytes,12,opt,name=local_workload_address,json=localWorkloadAddress,proto3" json:"local_workload_address,omitempty"` // Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. - LocalWorkloadPort uint32 `protobuf:"varint,14,opt,name=local_workload_port,json=localWorkloadPort,proto3" json:"local_workload_port,omitempty"` + LocalWorkloadPort uint32 `protobuf:"varint,13,opt,name=local_workload_port,json=localWorkloadPort,proto3" json:"local_workload_port,omitempty"` // Deprecated: Marked as deprecated in pbmesh/v2beta1/proxy_configuration.proto. - LocalWorkloadSocketPath string `protobuf:"bytes,15,opt,name=local_workload_socket_path,json=localWorkloadSocketPath,proto3" json:"local_workload_socket_path,omitempty"` + LocalWorkloadSocketPath string `protobuf:"bytes,14,opt,name=local_workload_socket_path,json=localWorkloadSocketPath,proto3" json:"local_workload_socket_path,omitempty"` } func (x *DynamicConfig) Reset() { @@ -402,13 +401,6 @@ func (x *DynamicConfig) GetAccessLogs() *AccessLogsConfig { return nil } -func (x *DynamicConfig) GetEnvoyExtensions() []*EnvoyExtension { - if x != nil { - return x.EnvoyExtensions - } - return nil -} - func (x *DynamicConfig) GetPublicListenerJson() string { if x != nil { return x.PublicListenerJson @@ -886,7 +878,7 @@ var file_pbmesh_v2beta1_proxy_configuration_proto_rawDesc = []byte{ 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0c, 0x6f, 0x70, 0x61, 0x71, 0x75, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x3a, 0x06, - 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0xeb, 0x09, 0x0a, 0x0d, 0x44, 0x79, 0x6e, 0x61, 0x6d, + 0xa2, 0x93, 0x04, 0x02, 0x08, 0x03, 0x22, 0x91, 0x09, 0x0a, 0x0d, 0x44, 0x79, 0x6e, 0x61, 0x6d, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x3c, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, @@ -932,154 +924,148 @@ var file_pbmesh_v2beta1_proxy_configuration_proto_rawDesc = []byte{ 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, - 0x67, 0x73, 0x12, 0x58, 0x0a, 0x10, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x5f, 0x65, 0x78, 0x74, 0x65, - 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 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, 0x2e, 0x45, 0x6e, 0x76, - 0x6f, 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x65, 0x6e, 0x76, - 0x6f, 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x14, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, - 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x32, - 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x69, - 0x6e, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x6c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x54, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x4a, 0x73, - 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, - 0x74, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, - 0x12, 0x38, 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, - 0x61, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x02, 0x18, 0x01, 0x52, 0x14, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, - 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x32, 0x0a, 0x13, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x70, 0x6f, 0x72, - 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x02, 0x18, 0x01, 0x52, 0x11, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x3f, - 0x0a, 0x1a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, - 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x0f, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x17, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, - 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x61, 0x74, 0x68, 0x1a, - 0x73, 0x0a, 0x14, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 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, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x71, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x34, 0x0a, 0x16, 0x6f, 0x75, 0x74, 0x62, - 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x6f, - 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, - 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x27, - 0x0a, 0x0f, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, - 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x44, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x22, 0x8e, 0x05, 0x0a, 0x0f, 0x42, 0x6f, 0x6f, 0x74, - 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x73, - 0x74, 0x61, 0x74, 0x73, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x6f, - 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x64, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x55, 0x72, 0x6c, 0x12, - 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x73, 0x54, 0x61, 0x67, 0x73, 0x12, 0x30, - 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x5f, 0x62, 0x69, 0x6e, - 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, - 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, - 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, - 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73, - 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, - 0x79, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x72, 0x65, 0x61, 0x64, 0x79, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, - 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x5f, 0x6a, 0x73, 0x6f, - 0x6e, 0x5f, 0x74, 0x70, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x6f, 0x76, 0x65, - 0x72, 0x72, 0x69, 0x64, 0x65, 0x4a, 0x73, 0x6f, 0x6e, 0x54, 0x70, 0x6c, 0x12, 0x30, 0x0a, 0x14, - 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x5f, - 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, - 0x69, 0x63, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x32, - 0x0a, 0x15, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, - 0x72, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, - 0x74, 0x61, 0x74, 0x69, 0x63, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x73, - 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x6b, - 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x73, 0x74, - 0x61, 0x74, 0x73, 0x53, 0x69, 0x6e, 0x6b, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, - 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, - 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, - 0x73, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, 0x73, 0x46, 0x6c, 0x75, - 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x72, - 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, - 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, - 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x4c, 0x0a, 0x23, 0x74, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x64, 0x69, - 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1f, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, - 0x72, 0x79, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x42, 0x69, 0x6e, 0x64, 0x53, - 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x44, 0x69, 0x72, 0x22, 0xf6, 0x01, 0x0a, 0x10, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, - 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4c, - 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x3e, 0x0a, 0x04, 0x74, - 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2a, 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, 0x2e, 0x4c, 0x6f, 0x67, 0x53, 0x69, 0x6e, - 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, - 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, - 0x1f, 0x0a, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6a, 0x73, 0x6f, 0x6e, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x78, 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, - 0x74, 0x22, 0xc3, 0x01, 0x0a, 0x0e, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, - 0x69, 0x72, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, - 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x65, 0x6e, 0x76, 0x6f, 0x79, - 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x56, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x78, 0x79, - 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, - 0x44, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, - 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, - 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x50, 0x52, 0x4f, 0x58, - 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x49, 0x52, 0x45, 0x43, 0x54, 0x10, 0x02, 0x2a, - 0x74, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x53, 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, - 0x0a, 0x15, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x47, - 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, - 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x10, 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4c, - 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x44, - 0x4f, 0x55, 0x54, 0x10, 0x03, 0x2a, 0x68, 0x0a, 0x0d, 0x4d, 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, - 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x17, 0x4d, 0x55, 0x54, 0x55, 0x41, 0x4c, - 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, - 0x54, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x55, 0x54, 0x55, 0x41, 0x4c, 0x5f, 0x54, 0x4c, - 0x53, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x43, 0x54, 0x10, 0x01, 0x12, - 0x1e, 0x0a, 0x1a, 0x4d, 0x55, 0x54, 0x55, 0x41, 0x4c, 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x4d, 0x4f, - 0x44, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x56, 0x45, 0x10, 0x02, 0x42, - 0x98, 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, 0x17, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, + 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6c, 0x69, 0x73, + 0x74, 0x65, 0x6e, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x12, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x5f, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x13, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x54, 0x72, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x5f, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6c, 0x75, 0x73, 0x74, + 0x65, 0x72, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x16, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, + 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x14, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x32, 0x0a, 0x13, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, + 0x61, 0x64, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x02, 0x18, + 0x01, 0x52, 0x11, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x3f, 0x0a, 0x1a, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x77, 0x6f, + 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x5f, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x5f, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x17, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x6f, 0x63, 0x6b, 0x65, + 0x74, 0x50, 0x61, 0x74, 0x68, 0x1a, 0x73, 0x0a, 0x14, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x45, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, + 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, 0x2e, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x71, 0x0a, 0x10, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x34, + 0x0a, 0x16, 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x14, + 0x6f, 0x75, 0x74, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, + 0x50, 0x6f, 0x72, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x61, 0x6c, 0x65, 0x64, 0x5f, 0x64, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x64, + 0x69, 0x61, 0x6c, 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6c, 0x79, 0x22, 0x8e, 0x05, + 0x0a, 0x0f, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, + 0x67, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x5f, 0x75, 0x72, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x55, 0x72, 0x6c, + 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, 0x73, 0x64, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x64, 0x6f, 0x67, 0x73, 0x74, 0x61, 0x74, + 0x73, 0x64, 0x55, 0x72, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x74, + 0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x73, + 0x54, 0x61, 0x67, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, + 0x75, 0x73, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x6d, 0x65, 0x74, 0x68, 0x65, 0x75, 0x73, 0x42, 0x69, + 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, + 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0d, 0x73, 0x74, 0x61, 0x74, 0x73, 0x42, 0x69, 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x26, + 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x79, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x72, 0x65, 0x61, 0x64, 0x79, 0x42, 0x69, + 0x6e, 0x64, 0x41, 0x64, 0x64, 0x72, 0x12, 0x2a, 0x0a, 0x11, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x74, 0x70, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0f, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x4a, 0x73, 0x6f, 0x6e, 0x54, + 0x70, 0x6c, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x12, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x73, + 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x32, 0x0a, 0x15, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x5f, 0x6c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x13, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x4c, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x65, 0x72, 0x73, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x73, 0x74, 0x61, 0x74, + 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x6b, 0x73, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x73, 0x53, 0x69, 0x6e, 0x6b, 0x73, 0x4a, 0x73, + 0x6f, 0x6e, 0x12, 0x2a, 0x0a, 0x11, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, 0x12, 0x30, + 0x0a, 0x14, 0x73, 0x74, 0x61, 0x74, 0x73, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x74, + 0x61, 0x74, 0x73, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, + 0x12, 0x2e, 0x0a, 0x13, 0x74, 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x6f, 0x6e, 0x66, + 0x69, 0x67, 0x5f, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x74, + 0x72, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x4a, 0x73, 0x6f, 0x6e, + 0x12, 0x4c, 0x0a, 0x23, 0x74, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x5f, 0x63, 0x6f, + 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x5f, 0x62, 0x69, 0x6e, 0x64, 0x5f, 0x73, 0x6f, 0x63, + 0x6b, 0x65, 0x74, 0x5f, 0x64, 0x69, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x09, 0x52, 0x1f, 0x74, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x42, 0x69, 0x6e, 0x64, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x44, 0x69, 0x72, 0x22, 0xf6, + 0x01, 0x0a, 0x10, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x6f, 0x67, 0x73, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x32, 0x0a, + 0x15, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, + 0x72, 0x5f, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x13, 0x64, 0x69, + 0x73, 0x61, 0x62, 0x6c, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, + 0x73, 0x12, 0x3e, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x2a, 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, 0x2e, + 0x4c, 0x6f, 0x67, 0x53, 0x69, 0x6e, 0x6b, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x6a, 0x73, 0x6f, 0x6e, 0x5f, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x6a, 0x73, 0x6f, 0x6e, + 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, 0x65, 0x78, 0x74, 0x5f, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x74, 0x65, 0x78, + 0x74, 0x46, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x22, 0xc3, 0x01, 0x0a, 0x0e, 0x45, 0x6e, 0x76, 0x6f, + 0x79, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x12, 0x35, 0x0a, 0x09, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x09, 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x76, 0x6f, + 0x79, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x65, 0x6e, 0x76, 0x6f, 0x79, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2a, 0x56, 0x0a, + 0x09, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x52, + 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, + 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, + 0x5f, 0x54, 0x52, 0x41, 0x4e, 0x53, 0x50, 0x41, 0x52, 0x45, 0x4e, 0x54, 0x10, 0x01, 0x12, 0x15, + 0x0a, 0x11, 0x50, 0x52, 0x4f, 0x58, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x44, 0x49, 0x52, + 0x45, 0x43, 0x54, 0x10, 0x02, 0x2a, 0x74, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x53, 0x69, 0x6e, 0x6b, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, + 0x16, 0x0a, 0x12, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x4f, 0x47, 0x5f, 0x53, + 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x54, 0x44, 0x45, 0x52, 0x52, 0x10, + 0x02, 0x12, 0x18, 0x0a, 0x14, 0x4c, 0x4f, 0x47, 0x5f, 0x53, 0x49, 0x4e, 0x4b, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x53, 0x54, 0x44, 0x4f, 0x55, 0x54, 0x10, 0x03, 0x2a, 0x68, 0x0a, 0x0d, 0x4d, + 0x75, 0x74, 0x75, 0x61, 0x6c, 0x54, 0x4c, 0x53, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1b, 0x0a, 0x17, + 0x4d, 0x55, 0x54, 0x55, 0x41, 0x4c, 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, + 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, 0x00, 0x12, 0x1a, 0x0a, 0x16, 0x4d, 0x55, 0x54, + 0x55, 0x41, 0x4c, 0x5f, 0x54, 0x4c, 0x53, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x52, + 0x49, 0x43, 0x54, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x4d, 0x55, 0x54, 0x55, 0x41, 0x4c, 0x5f, + 0x54, 0x4c, 0x53, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, + 0x49, 0x56, 0x45, 0x10, 0x02, 0x42, 0x98, 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, 0x17, 0x50, 0x72, 0x6f, + 0x78, 0x79, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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 ( @@ -1127,15 +1113,14 @@ var file_pbmesh_v2beta1_proxy_configuration_proto_depIdxs = []int32{ 13, // 9: hashicorp.consul.mesh.v2beta1.DynamicConfig.mesh_gateway_mode:type_name -> hashicorp.consul.mesh.v2beta1.MeshGatewayMode 14, // 10: hashicorp.consul.mesh.v2beta1.DynamicConfig.expose_config:type_name -> hashicorp.consul.mesh.v2beta1.ExposeConfig 7, // 11: hashicorp.consul.mesh.v2beta1.DynamicConfig.access_logs:type_name -> hashicorp.consul.mesh.v2beta1.AccessLogsConfig - 8, // 12: hashicorp.consul.mesh.v2beta1.DynamicConfig.envoy_extensions:type_name -> hashicorp.consul.mesh.v2beta1.EnvoyExtension - 1, // 13: hashicorp.consul.mesh.v2beta1.AccessLogsConfig.type:type_name -> hashicorp.consul.mesh.v2beta1.LogSinkType - 11, // 14: hashicorp.consul.mesh.v2beta1.EnvoyExtension.arguments:type_name -> google.protobuf.Struct - 15, // 15: hashicorp.consul.mesh.v2beta1.DynamicConfig.LocalConnectionEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.ConnectionConfig - 16, // [16:16] is the sub-list for method output_type - 16, // [16:16] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name + 1, // 12: hashicorp.consul.mesh.v2beta1.AccessLogsConfig.type:type_name -> hashicorp.consul.mesh.v2beta1.LogSinkType + 11, // 13: hashicorp.consul.mesh.v2beta1.EnvoyExtension.arguments:type_name -> google.protobuf.Struct + 15, // 14: hashicorp.consul.mesh.v2beta1.DynamicConfig.LocalConnectionEntry.value:type_name -> hashicorp.consul.mesh.v2beta1.ConnectionConfig + 15, // [15:15] is the sub-list for method output_type + 15, // [15:15] is the sub-list for method input_type + 15, // [15:15] is the sub-list for extension type_name + 15, // [15:15] is the sub-list for extension extendee + 0, // [0:15] is the sub-list for field type_name } func init() { file_pbmesh_v2beta1_proxy_configuration_proto_init() } diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration.proto b/proto-public/pbmesh/v2beta1/proxy_configuration.proto index eb47e16e2282..9a2d410d868d 100644 --- a/proto-public/pbmesh/v2beta1/proxy_configuration.proto +++ b/proto-public/pbmesh/v2beta1/proxy_configuration.proto @@ -60,18 +60,16 @@ message DynamicConfig { // AccessLogs configures the output and format of Envoy access logs AccessLogsConfig access_logs = 8; - repeated EnvoyExtension envoy_extensions = 9; - - string public_listener_json = 10; - string listener_tracing_json = 11; - string local_cluster_json = 12; + string public_listener_json = 9; + string listener_tracing_json = 10; + string local_cluster_json = 11; // deprecated: // local_workload_address, local_workload_port, and local_workload_socket_path // are deprecated and are only needed for migration of existing resources. - string local_workload_address = 13 [deprecated = true]; - uint32 local_workload_port = 14 [deprecated = true]; - string local_workload_socket_path = 15 [deprecated = true]; + string local_workload_address = 12 [deprecated = true]; + uint32 local_workload_port = 13 [deprecated = true]; + string local_workload_socket_path = 14 [deprecated = true]; } message TransparentProxy { diff --git a/proto-public/pbmesh/v2beta1/proxy_configuration_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/proxy_configuration_deepcopy.gen.go index 8c185f882017..bc5b81a9a6fb 100644 --- a/proto-public/pbmesh/v2beta1/proxy_configuration_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/proxy_configuration_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ProxyConfiguration within kubernetes types, where deepcopy-gen is used. func (in *ProxyConfiguration) DeepCopyInto(out *ProxyConfiguration) { - p := proto.Clone(in).(*ProxyConfiguration) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyConfiguration. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *ProxyConfiguration) DeepCopyInterface() interface{} { // DeepCopyInto supports using DynamicConfig within kubernetes types, where deepcopy-gen is used. func (in *DynamicConfig) DeepCopyInto(out *DynamicConfig) { - p := proto.Clone(in).(*DynamicConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DynamicConfig. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *DynamicConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using TransparentProxy within kubernetes types, where deepcopy-gen is used. func (in *TransparentProxy) DeepCopyInto(out *TransparentProxy) { - p := proto.Clone(in).(*TransparentProxy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TransparentProxy. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *TransparentProxy) DeepCopyInterface() interface{} { // DeepCopyInto supports using BootstrapConfig within kubernetes types, where deepcopy-gen is used. func (in *BootstrapConfig) DeepCopyInto(out *BootstrapConfig) { - p := proto.Clone(in).(*BootstrapConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BootstrapConfig. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *BootstrapConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using AccessLogsConfig within kubernetes types, where deepcopy-gen is used. func (in *AccessLogsConfig) DeepCopyInto(out *AccessLogsConfig) { - p := proto.Clone(in).(*AccessLogsConfig) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AccessLogsConfig. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *AccessLogsConfig) DeepCopyInterface() interface{} { // DeepCopyInto supports using EnvoyExtension within kubernetes types, where deepcopy-gen is used. func (in *EnvoyExtension) DeepCopyInto(out *EnvoyExtension) { - p := proto.Clone(in).(*EnvoyExtension) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoyExtension. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/proxy_state_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/proxy_state_deepcopy.gen.go index c6d34360e0f9..fbc6ed842098 100644 --- a/proto-public/pbmesh/v2beta1/proxy_state_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/proxy_state_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ProxyStateTemplate within kubernetes types, where deepcopy-gen is used. func (in *ProxyStateTemplate) DeepCopyInto(out *ProxyStateTemplate) { - p := proto.Clone(in).(*ProxyStateTemplate) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyStateTemplate. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *ProxyStateTemplate) DeepCopyInterface() interface{} { // DeepCopyInto supports using ProxyState within kubernetes types, where deepcopy-gen is used. func (in *ProxyState) DeepCopyInto(out *ProxyState) { - p := proto.Clone(in).(*ProxyState) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyState. Required by controller-gen. diff --git a/proto-public/pbmesh/v2beta1/routing.pb.go b/proto-public/pbmesh/v2beta1/routing.pb.go index 163632eb3054..4b1f64877431 100644 --- a/proto-public/pbmesh/v2beta1/routing.pb.go +++ b/proto-public/pbmesh/v2beta1/routing.pb.go @@ -29,7 +29,7 @@ type MeshGatewayMode int32 const ( // MESH_GATEWAY_MODE_UNSPECIFIED represents no specific mode and should be - // used to indicate that a the decision on the mode will be made by other + // used to indicate that the decision on the mode will be made by other // configuration or default settings. MeshGatewayMode_MESH_GATEWAY_MODE_UNSPECIFIED MeshGatewayMode = 0 // MESH_GATEWAY_MODE_NONE is the mode to use when traffic should not be diff --git a/proto-public/pbmesh/v2beta1/routing.proto b/proto-public/pbmesh/v2beta1/routing.proto index 5c28840a72dc..b09d28a6458a 100644 --- a/proto-public/pbmesh/v2beta1/routing.proto +++ b/proto-public/pbmesh/v2beta1/routing.proto @@ -9,7 +9,7 @@ package hashicorp.consul.mesh.v2beta1; // +kubebuilder:validation:Type=string enum MeshGatewayMode { // MESH_GATEWAY_MODE_UNSPECIFIED represents no specific mode and should be - // used to indicate that a the decision on the mode will be made by other + // used to indicate that the decision on the mode will be made by other // configuration or default settings. MESH_GATEWAY_MODE_UNSPECIFIED = 0; diff --git a/proto-public/pbmesh/v2beta1/tcp_route_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/tcp_route_deepcopy.gen.go index c2bd4afc57f8..487209766f96 100644 --- a/proto-public/pbmesh/v2beta1/tcp_route_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/tcp_route_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using TCPRoute within kubernetes types, where deepcopy-gen is used. func (in *TCPRoute) DeepCopyInto(out *TCPRoute) { - p := proto.Clone(in).(*TCPRoute) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPRoute. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *TCPRoute) DeepCopyInterface() interface{} { // DeepCopyInto supports using TCPRouteRule within kubernetes types, where deepcopy-gen is used. func (in *TCPRouteRule) DeepCopyInto(out *TCPRouteRule) { - p := proto.Clone(in).(*TCPRouteRule) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPRouteRule. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *TCPRouteRule) DeepCopyInterface() interface{} { // DeepCopyInto supports using TCPBackendRef within kubernetes types, where deepcopy-gen is used. func (in *TCPBackendRef) DeepCopyInto(out *TCPBackendRef) { - p := proto.Clone(in).(*TCPBackendRef) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPBackendRef. Required by controller-gen. diff --git a/proto-public/pbresource/annotations_deepcopy.gen.go b/proto-public/pbresource/annotations_deepcopy.gen.go index a4265c38505c..0693ee89e2e5 100644 --- a/proto-public/pbresource/annotations_deepcopy.gen.go +++ b/proto-public/pbresource/annotations_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using ResourceTypeSpec within kubernetes types, where deepcopy-gen is used. func (in *ResourceTypeSpec) DeepCopyInto(out *ResourceTypeSpec) { - p := proto.Clone(in).(*ResourceTypeSpec) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceTypeSpec. Required by controller-gen. diff --git a/proto-public/pbresource/resource_deepcopy.gen.go b/proto-public/pbresource/resource_deepcopy.gen.go index 92fdb8da2f46..5b81e6f9dfed 100644 --- a/proto-public/pbresource/resource_deepcopy.gen.go +++ b/proto-public/pbresource/resource_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Type within kubernetes types, where deepcopy-gen is used. func (in *Type) DeepCopyInto(out *Type) { - p := proto.Clone(in).(*Type) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Type. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *Type) DeepCopyInterface() interface{} { // DeepCopyInto supports using Tenancy within kubernetes types, where deepcopy-gen is used. func (in *Tenancy) DeepCopyInto(out *Tenancy) { - p := proto.Clone(in).(*Tenancy) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tenancy. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *Tenancy) DeepCopyInterface() interface{} { // DeepCopyInto supports using ID within kubernetes types, where deepcopy-gen is used. func (in *ID) DeepCopyInto(out *ID) { - p := proto.Clone(in).(*ID) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ID. Required by controller-gen. @@ -70,8 +70,8 @@ func (in *ID) DeepCopyInterface() interface{} { // DeepCopyInto supports using Resource within kubernetes types, where deepcopy-gen is used. func (in *Resource) DeepCopyInto(out *Resource) { - p := proto.Clone(in).(*Resource) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resource. Required by controller-gen. @@ -91,8 +91,8 @@ func (in *Resource) DeepCopyInterface() interface{} { // DeepCopyInto supports using Status within kubernetes types, where deepcopy-gen is used. func (in *Status) DeepCopyInto(out *Status) { - p := proto.Clone(in).(*Status) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status. Required by controller-gen. @@ -112,8 +112,8 @@ func (in *Status) DeepCopyInterface() interface{} { // DeepCopyInto supports using Condition within kubernetes types, where deepcopy-gen is used. func (in *Condition) DeepCopyInto(out *Condition) { - p := proto.Clone(in).(*Condition) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Condition. Required by controller-gen. @@ -133,8 +133,8 @@ func (in *Condition) DeepCopyInterface() interface{} { // DeepCopyInto supports using Reference within kubernetes types, where deepcopy-gen is used. func (in *Reference) DeepCopyInto(out *Reference) { - p := proto.Clone(in).(*Reference) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Reference. Required by controller-gen. @@ -154,8 +154,8 @@ func (in *Reference) DeepCopyInterface() interface{} { // DeepCopyInto supports using Tombstone within kubernetes types, where deepcopy-gen is used. func (in *Tombstone) DeepCopyInto(out *Tombstone) { - p := proto.Clone(in).(*Tombstone) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tombstone. Required by controller-gen. @@ -175,8 +175,8 @@ func (in *Tombstone) DeepCopyInterface() interface{} { // DeepCopyInto supports using ReadRequest within kubernetes types, where deepcopy-gen is used. func (in *ReadRequest) DeepCopyInto(out *ReadRequest) { - p := proto.Clone(in).(*ReadRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadRequest. Required by controller-gen. @@ -196,8 +196,8 @@ func (in *ReadRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using ReadResponse within kubernetes types, where deepcopy-gen is used. func (in *ReadResponse) DeepCopyInto(out *ReadResponse) { - p := proto.Clone(in).(*ReadResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ReadResponse. Required by controller-gen. @@ -217,8 +217,8 @@ func (in *ReadResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using ListRequest within kubernetes types, where deepcopy-gen is used. func (in *ListRequest) DeepCopyInto(out *ListRequest) { - p := proto.Clone(in).(*ListRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListRequest. Required by controller-gen. @@ -238,8 +238,8 @@ func (in *ListRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using ListResponse within kubernetes types, where deepcopy-gen is used. func (in *ListResponse) DeepCopyInto(out *ListResponse) { - p := proto.Clone(in).(*ListResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListResponse. Required by controller-gen. @@ -259,8 +259,8 @@ func (in *ListResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using ListByOwnerRequest within kubernetes types, where deepcopy-gen is used. func (in *ListByOwnerRequest) DeepCopyInto(out *ListByOwnerRequest) { - p := proto.Clone(in).(*ListByOwnerRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListByOwnerRequest. Required by controller-gen. @@ -280,8 +280,8 @@ func (in *ListByOwnerRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using ListByOwnerResponse within kubernetes types, where deepcopy-gen is used. func (in *ListByOwnerResponse) DeepCopyInto(out *ListByOwnerResponse) { - p := proto.Clone(in).(*ListByOwnerResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ListByOwnerResponse. Required by controller-gen. @@ -301,8 +301,8 @@ func (in *ListByOwnerResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using WriteRequest within kubernetes types, where deepcopy-gen is used. func (in *WriteRequest) DeepCopyInto(out *WriteRequest) { - p := proto.Clone(in).(*WriteRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WriteRequest. Required by controller-gen. @@ -322,8 +322,8 @@ func (in *WriteRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using WriteResponse within kubernetes types, where deepcopy-gen is used. func (in *WriteResponse) DeepCopyInto(out *WriteResponse) { - p := proto.Clone(in).(*WriteResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WriteResponse. Required by controller-gen. @@ -343,8 +343,8 @@ func (in *WriteResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using WriteStatusRequest within kubernetes types, where deepcopy-gen is used. func (in *WriteStatusRequest) DeepCopyInto(out *WriteStatusRequest) { - p := proto.Clone(in).(*WriteStatusRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WriteStatusRequest. Required by controller-gen. @@ -364,8 +364,8 @@ func (in *WriteStatusRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using WriteStatusResponse within kubernetes types, where deepcopy-gen is used. func (in *WriteStatusResponse) DeepCopyInto(out *WriteStatusResponse) { - p := proto.Clone(in).(*WriteStatusResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WriteStatusResponse. Required by controller-gen. @@ -385,8 +385,8 @@ func (in *WriteStatusResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using DeleteRequest within kubernetes types, where deepcopy-gen is used. func (in *DeleteRequest) DeepCopyInto(out *DeleteRequest) { - p := proto.Clone(in).(*DeleteRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeleteRequest. Required by controller-gen. @@ -406,8 +406,8 @@ func (in *DeleteRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using DeleteResponse within kubernetes types, where deepcopy-gen is used. func (in *DeleteResponse) DeepCopyInto(out *DeleteResponse) { - p := proto.Clone(in).(*DeleteResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeleteResponse. Required by controller-gen. @@ -427,8 +427,8 @@ func (in *DeleteResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using WatchListRequest within kubernetes types, where deepcopy-gen is used. func (in *WatchListRequest) DeepCopyInto(out *WatchListRequest) { - p := proto.Clone(in).(*WatchListRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchListRequest. Required by controller-gen. @@ -448,8 +448,8 @@ func (in *WatchListRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using WatchEvent within kubernetes types, where deepcopy-gen is used. func (in *WatchEvent) DeepCopyInto(out *WatchEvent) { - p := proto.Clone(in).(*WatchEvent) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchEvent. Required by controller-gen. diff --git a/proto-public/pbserverdiscovery/serverdiscovery_deepcopy.gen.go b/proto-public/pbserverdiscovery/serverdiscovery_deepcopy.gen.go index 6d5016561427..2bd82a8a891a 100644 --- a/proto-public/pbserverdiscovery/serverdiscovery_deepcopy.gen.go +++ b/proto-public/pbserverdiscovery/serverdiscovery_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using WatchServersRequest within kubernetes types, where deepcopy-gen is used. func (in *WatchServersRequest) DeepCopyInto(out *WatchServersRequest) { - p := proto.Clone(in).(*WatchServersRequest) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchServersRequest. Required by controller-gen. @@ -28,8 +28,8 @@ func (in *WatchServersRequest) DeepCopyInterface() interface{} { // DeepCopyInto supports using WatchServersResponse within kubernetes types, where deepcopy-gen is used. func (in *WatchServersResponse) DeepCopyInto(out *WatchServersResponse) { - p := proto.Clone(in).(*WatchServersResponse) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WatchServersResponse. Required by controller-gen. @@ -49,8 +49,8 @@ func (in *WatchServersResponse) DeepCopyInterface() interface{} { // DeepCopyInto supports using Server within kubernetes types, where deepcopy-gen is used. func (in *Server) DeepCopyInto(out *Server) { - p := proto.Clone(in).(*Server) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Server. Required by controller-gen. diff --git a/proto-public/pbtenancy/v1alpha1/namespace_deepcopy.gen.go b/proto-public/pbtenancy/v1alpha1/namespace_deepcopy.gen.go index 52ee3d7e7cc7..97af531ab333 100644 --- a/proto-public/pbtenancy/v1alpha1/namespace_deepcopy.gen.go +++ b/proto-public/pbtenancy/v1alpha1/namespace_deepcopy.gen.go @@ -7,8 +7,8 @@ import ( // DeepCopyInto supports using Namespace within kubernetes types, where deepcopy-gen is used. func (in *Namespace) DeepCopyInto(out *Namespace) { - p := proto.Clone(in).(*Namespace) - *out = *p + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Namespace. Required by controller-gen. diff --git a/proto/private/pbconfigentry/config_entry.gen.go b/proto/private/pbconfigentry/config_entry.gen.go index 258d8dbb6df6..6f9b53e01db7 100644 --- a/proto/private/pbconfigentry/config_entry.gen.go +++ b/proto/private/pbconfigentry/config_entry.gen.go @@ -1822,19 +1822,19 @@ func RetryFilterToStructs(s *RetryFilter, t *structs.RetryFilter) { if s == nil { return } - t.NumRetries = &s.NumRetries + t.NumRetries = s.NumRetries t.RetryOn = s.RetryOn t.RetryOnStatusCodes = s.RetryOnStatusCodes - t.RetryOnConnectFailure = &s.RetryOnConnectFailure + t.RetryOnConnectFailure = s.RetryOnConnectFailure } func RetryFilterFromStructs(t *structs.RetryFilter, s *RetryFilter) { if s == nil { return } - s.NumRetries = *t.NumRetries + s.NumRetries = t.NumRetries s.RetryOn = t.RetryOn s.RetryOnStatusCodes = t.RetryOnStatusCodes - s.RetryOnConnectFailure = *t.RetryOnConnectFailure + s.RetryOnConnectFailure = t.RetryOnConnectFailure } func RetryPolicyBackOffToStructs(s *RetryPolicyBackOff, t *structs.RetryPolicyBackOff) { if s == nil { diff --git a/sdk/.copywrite.hcl b/sdk/.copywrite.hcl new file mode 100644 index 000000000000..34d99ba25e12 --- /dev/null +++ b/sdk/.copywrite.hcl @@ -0,0 +1,8 @@ +schema_version = 1 + +project { + license = "MPL-2.0" + copyright_year = 2023 + + header_ignore = [] +} diff --git a/sdk/go.mod b/sdk/go.mod index 9fd95927b085..f4adaf73ba79 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -9,7 +9,7 @@ require ( github.com/hashicorp/go-version v1.2.1 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.8.3 - golang.org/x/sys v0.10.0 + golang.org/x/sys v0.13.0 ) require ( diff --git a/sdk/go.sum b/sdk/go.sum index 170d4464fc55..490559d90093 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -49,8 +49,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/sdk/testutil/retry/counter.go b/sdk/testutil/retry/counter.go index 96a37ab9d2fc..ffd509f1a414 100644 --- a/sdk/testutil/retry/counter.go +++ b/sdk/testutil/retry/counter.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package retry import "time" diff --git a/sdk/testutil/retry/timer.go b/sdk/testutil/retry/timer.go index 16433e9ec7b0..be4f5e92f407 100644 --- a/sdk/testutil/retry/timer.go +++ b/sdk/testutil/retry/timer.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package retry import "time" diff --git a/test-integ/Makefile b/test-integ/Makefile new file mode 100644 index 000000000000..0fd35d4eda7e --- /dev/null +++ b/test-integ/Makefile @@ -0,0 +1,42 @@ +SHELL := /bin/bash + +.PHONY: noop +noop: + +##@ Build + +.PHONY: tidy +tidy: ## Run go mod tidy. + go mod tidy + +##@ Checks + +.PHONY: format +format: ## Format the go files. + @for f in $$(find . -name '*.go' -print); do \ + gofmt -s -w $$f ; \ + done + +.PHONY: lint +lint: ## Run the full linting rules. + golangci-lint run -v + +.PHONY: vet +vet: ## Run go vet. + go vet ./... + +##@ Help + +# The help target prints out all targets with their descriptions organized +# beneath their categories. The categories are represented by '##@' and the +# target descriptions by '##'. The awk commands is responsible for reading the +# entire set of makefiles included in this invocation, looking for lines of the +# file as xyz: ## something, and then pretty-format the target and help. Then, +# if there's a line with ##@ something, that gets pretty-printed as a category. +# More info on the usage of ANSI control characters for terminal formatting: +# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info on the awk command: +# http://linuxcommand.org/lc3_adv_awk.php +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) diff --git a/test-integ/catalogv2/explicit_destinations_test.go b/test-integ/catalogv2/explicit_destinations_test.go new file mode 100644 index 000000000000..9c86e0595261 --- /dev/null +++ b/test-integ/catalogv2/explicit_destinations_test.go @@ -0,0 +1,274 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package catalogv2 + +import ( + "fmt" + "testing" + + pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" + libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" + "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" + "github.com/hashicorp/consul/testing/deployer/topology" + + "github.com/hashicorp/consul/test-integ/topoutil" +) + +// TestBasicL4ExplicitDestinations sets up the following: +// +// - 1 cluster (no peering / no wanfed) +// - 3 servers in that cluster +// - v2 arch is activated +// - for each tenancy, only using v2 constructs: +// - a client with one explicit destination to a single port service +// - a client with multiple explicit destinations to multiple ports of the +// same multiport service +// +// When this test is executed in CE it will only use the default/default +// tenancy. +// +// When this test is executed in Enterprise it will additionally test the same +// things within these tenancies: +// +// - part1/default +// - default/nsa +// - part1/nsa +func TestBasicL4ExplicitDestinations(t *testing.T) { + cfg := testBasicL4ExplicitDestinationsCreator{}.NewConfig(t) + + sp := sprawltest.Launch(t, cfg) + + var ( + asserter = topoutil.NewAsserter(sp) + + topo = sp.Topology() + cluster = topo.Clusters["dc1"] + + ships = topo.ComputeRelationships() + ) + + clientV2 := sp.ResourceServiceClientForCluster(cluster.Name) + + t.Log(topology.RenderRelationships(ships)) + + // Make sure things are in v2. + for _, name := range []string{ + "single-server", + "single-client", + "multi-server", + "multi-client", + } { + libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, name, nil, 1) + } + + // Check relationships + for _, ship := range ships { + t.Run("relationship: "+ship.String(), func(t *testing.T) { + var ( + svc = ship.Caller + u = ship.Upstream + ) + + clusterPrefix := clusterPrefixForUpstream(u) + + asserter.UpstreamEndpointStatus(t, svc, clusterPrefix+".", "HEALTHY", 1) + asserter.HTTPServiceEchoes(t, svc, u.LocalPort, "") + asserter.FortioFetch2FortioName(t, svc, u, cluster.Name, u.ID) + }) + } +} + +type testBasicL4ExplicitDestinationsCreator struct{} + +func (c testBasicL4ExplicitDestinationsCreator) NewConfig(t *testing.T) *topology.Config { + const clusterName = "dc1" + + servers := topoutil.NewTopologyServerSet(clusterName+"-server", 3, []string{clusterName, "wan"}, nil) + + cluster := &topology.Cluster{ + Enterprise: utils.IsEnterprise(), + Name: clusterName, + Nodes: servers, + } + + lastNode := 0 + nodeName := func() string { + lastNode++ + return fmt.Sprintf("%s-box%d", clusterName, lastNode) + } + + c.topologyConfigAddNodes(t, cluster, nodeName, "default", "default") + if cluster.Enterprise { + c.topologyConfigAddNodes(t, cluster, nodeName, "part1", "default") + c.topologyConfigAddNodes(t, cluster, nodeName, "part1", "nsa") + c.topologyConfigAddNodes(t, cluster, nodeName, "default", "nsa") + } + + return &topology.Config{ + Images: topoutil.TargetImages(), + Networks: []*topology.Network{ + {Name: clusterName}, + {Name: "wan", Type: "wan"}, + }, + Clusters: []*topology.Cluster{ + cluster, + }, + } +} + +func (c testBasicL4ExplicitDestinationsCreator) topologyConfigAddNodes( + t *testing.T, + cluster *topology.Cluster, + nodeName func() string, + partition, + namespace string, +) { + clusterName := cluster.Name + + newServiceID := func(name string) topology.ServiceID { + return topology.ServiceID{ + Partition: partition, + Namespace: namespace, + Name: name, + } + } + + tenancy := &pbresource.Tenancy{ + Partition: partition, + Namespace: namespace, + PeerName: "local", + } + + singleportServerNode := &topology.Node{ + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Partition: partition, + Name: nodeName(), + Services: []*topology.Service{ + topoutil.NewFortioServiceWithDefaults( + clusterName, + newServiceID("single-server"), + topology.NodeVersionV2, + nil, + ), + }, + } + singleportClientNode := &topology.Node{ + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Partition: partition, + Name: nodeName(), + Services: []*topology.Service{ + topoutil.NewFortioServiceWithDefaults( + clusterName, + newServiceID("single-client"), + topology.NodeVersionV2, + func(svc *topology.Service) { + delete(svc.Ports, "grpc") // v2 mode turns this on, so turn it off + delete(svc.Ports, "http-alt") // v2 mode turns this on, so turn it off + svc.Upstreams = []*topology.Upstream{{ + ID: newServiceID("single-server"), + PortName: "http", + LocalAddress: "0.0.0.0", // needed for an assertion + LocalPort: 5000, + }} + }, + ), + }, + } + singleportTrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbauth.TrafficPermissionsType, + Name: "single-server-perms", + Tenancy: tenancy, + }, + }, &pbauth.TrafficPermissions{ + Destination: &pbauth.Destination{ + IdentityName: "single-server", + }, + Action: pbauth.Action_ACTION_ALLOW, + Permissions: []*pbauth.Permission{{ + Sources: []*pbauth.Source{{ + IdentityName: "single-client", + Namespace: namespace, + }}, + }}, + }) + + multiportServerNode := &topology.Node{ + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Partition: partition, + Name: nodeName(), + Services: []*topology.Service{ + topoutil.NewFortioServiceWithDefaults( + clusterName, + newServiceID("multi-server"), + topology.NodeVersionV2, + nil, + ), + }, + } + multiportClientNode := &topology.Node{ + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Partition: partition, + Name: nodeName(), + Services: []*topology.Service{ + topoutil.NewFortioServiceWithDefaults( + clusterName, + newServiceID("multi-client"), + topology.NodeVersionV2, + func(svc *topology.Service) { + svc.Upstreams = []*topology.Upstream{ + { + ID: newServiceID("multi-server"), + PortName: "http", + LocalAddress: "0.0.0.0", // needed for an assertion + LocalPort: 5000, + }, + { + ID: newServiceID("multi-server"), + PortName: "http-alt", + LocalAddress: "0.0.0.0", // needed for an assertion + LocalPort: 5001, + }, + } + }, + ), + }, + } + multiportTrafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbauth.TrafficPermissionsType, + Name: "multi-server-perms", + Tenancy: tenancy, + }, + }, &pbauth.TrafficPermissions{ + Destination: &pbauth.Destination{ + IdentityName: "multi-server", + }, + Action: pbauth.Action_ACTION_ALLOW, + Permissions: []*pbauth.Permission{{ + Sources: []*pbauth.Source{{ + IdentityName: "multi-client", + Namespace: namespace, + }}, + }}, + }) + + cluster.Nodes = append(cluster.Nodes, + singleportClientNode, + singleportServerNode, + multiportClientNode, + multiportServerNode, + ) + + cluster.InitialResources = append(cluster.InitialResources, + singleportTrafficPerms, + multiportTrafficPerms, + ) +} diff --git a/test-integ/catalogv2/helpers_test.go b/test-integ/catalogv2/helpers_test.go new file mode 100644 index 000000000000..f5e352779a29 --- /dev/null +++ b/test-integ/catalogv2/helpers_test.go @@ -0,0 +1,22 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package catalogv2 + +import ( + "strings" + + "github.com/hashicorp/consul/testing/deployer/topology" +) + +func clusterPrefixForUpstream(u *topology.Upstream) string { + if u.Peer == "" { + if u.ID.PartitionOrDefault() == "default" { + return strings.Join([]string{u.PortName, u.ID.Name, u.ID.Namespace, u.Cluster, "internal"}, ".") + } else { + return strings.Join([]string{u.PortName, u.ID.Name, u.ID.Namespace, u.ID.Partition, u.Cluster, "internal-v1"}, ".") + } + } else { + return strings.Join([]string{u.ID.Name, u.ID.Namespace, u.Peer, "external"}, ".") + } +} diff --git a/test-integ/catalogv2/implicit_destinations_test.go b/test-integ/catalogv2/implicit_destinations_test.go new file mode 100644 index 000000000000..daf19945a9e3 --- /dev/null +++ b/test-integ/catalogv2/implicit_destinations_test.go @@ -0,0 +1,214 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package catalogv2 + +import ( + "fmt" + "testing" + + pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" + libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" + "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" + "github.com/hashicorp/consul/testing/deployer/topology" + + "github.com/hashicorp/consul/test-integ/topoutil" +) + +// TestBasicL4ImplicitDestinations sets up the following: +// +// - 1 cluster (no peering / no wanfed) +// - 3 servers in that cluster +// - v2 arch is activated +// - for each tenancy, only using v2 constructs: +// - a server exposing 2 tcp ports +// - a client with transparent proxy enabled and no explicit upstreams +// - a traffic permission granting the client access to the service on all ports +// +// When this test is executed in CE it will only use the default/default +// tenancy. +// +// When this test is executed in Enterprise it will additionally test the same +// things within these tenancies: +// +// - part1/default +// - default/nsa +// - part1/nsa +func TestBasicL4ImplicitDestinations(t *testing.T) { + cfg := testBasicL4ImplicitDestinationsCreator{}.NewConfig(t) + + sp := sprawltest.Launch(t, cfg) + + var ( + asserter = topoutil.NewAsserter(sp) + + topo = sp.Topology() + cluster = topo.Clusters["dc1"] + + ships = topo.ComputeRelationships() + ) + + clientV2 := sp.ResourceServiceClientForCluster(cluster.Name) + + t.Log(topology.RenderRelationships(ships)) + + // Make sure things are truly in v2 not v1. + for _, name := range []string{ + "static-server", + "static-client", + } { + libassert.CatalogV2ServiceHasEndpointCount(t, clientV2, name, nil, 1) + } + + // Check relationships + for _, ship := range ships { + t.Run("relationship: "+ship.String(), func(t *testing.T) { + var ( + svc = ship.Caller + u = ship.Upstream + ) + + clusterPrefix := clusterPrefixForUpstream(u) + + asserter.UpstreamEndpointStatus(t, svc, clusterPrefix+".", "HEALTHY", 1) + if u.LocalPort > 0 { + asserter.HTTPServiceEchoes(t, svc, u.LocalPort, "") + } + asserter.FortioFetch2FortioName(t, svc, u, cluster.Name, u.ID) + }) + } +} + +type testBasicL4ImplicitDestinationsCreator struct{} + +func (c testBasicL4ImplicitDestinationsCreator) NewConfig(t *testing.T) *topology.Config { + const clusterName = "dc1" + + servers := topoutil.NewTopologyServerSet(clusterName+"-server", 3, []string{clusterName, "wan"}, nil) + + cluster := &topology.Cluster{ + Enterprise: utils.IsEnterprise(), + Name: clusterName, + Nodes: servers, + } + + lastNode := 0 + nodeName := func() string { + lastNode++ + return fmt.Sprintf("%s-box%d", clusterName, lastNode) + } + + c.topologyConfigAddNodes(t, cluster, nodeName, "default", "default") + if cluster.Enterprise { + c.topologyConfigAddNodes(t, cluster, nodeName, "part1", "default") + c.topologyConfigAddNodes(t, cluster, nodeName, "part1", "nsa") + c.topologyConfigAddNodes(t, cluster, nodeName, "default", "nsa") + } + + return &topology.Config{ + Images: topoutil.TargetImages(), + Networks: []*topology.Network{ + {Name: clusterName}, + {Name: "wan", Type: "wan"}, + }, + Clusters: []*topology.Cluster{ + cluster, + }, + } +} + +func (c testBasicL4ImplicitDestinationsCreator) topologyConfigAddNodes( + t *testing.T, + cluster *topology.Cluster, + nodeName func() string, + partition, + namespace string, +) { + clusterName := cluster.Name + + newServiceID := func(name string) topology.ServiceID { + return topology.ServiceID{ + Partition: partition, + Namespace: namespace, + Name: name, + } + } + + tenancy := &pbresource.Tenancy{ + Partition: partition, + Namespace: namespace, + PeerName: "local", + } + + serverNode := &topology.Node{ + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Partition: partition, + Name: nodeName(), + Services: []*topology.Service{ + topoutil.NewFortioServiceWithDefaults( + clusterName, + newServiceID("static-server"), + topology.NodeVersionV2, + func(svc *topology.Service) { + svc.EnableTransparentProxy = true + }, + ), + }, + } + clientNode := &topology.Node{ + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Partition: partition, + Name: nodeName(), + Services: []*topology.Service{ + topoutil.NewFortioServiceWithDefaults( + clusterName, + newServiceID("static-client"), + topology.NodeVersionV2, + func(svc *topology.Service) { + svc.EnableTransparentProxy = true + svc.ImpliedUpstreams = []*topology.Upstream{ + { + ID: newServiceID("static-server"), + PortName: "http", + }, + { + ID: newServiceID("static-server"), + PortName: "http-alt", + }, + } + }, + ), + }, + } + trafficPerms := sprawltest.MustSetResourceData(t, &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbauth.TrafficPermissionsType, + Name: "static-server-perms", + Tenancy: tenancy, + }, + }, &pbauth.TrafficPermissions{ + Destination: &pbauth.Destination{ + IdentityName: "static-server", + }, + Action: pbauth.Action_ACTION_ALLOW, + Permissions: []*pbauth.Permission{{ + Sources: []*pbauth.Source{{ + IdentityName: "static-client", + Namespace: namespace, + }}, + }}, + }) + + cluster.Nodes = append(cluster.Nodes, + clientNode, + serverNode, + ) + + cluster.InitialResources = append(cluster.InitialResources, + trafficPerms, + ) +} diff --git a/test-integ/connect/snapshot_test.go b/test-integ/connect/snapshot_test.go new file mode 100644 index 000000000000..469562a16074 --- /dev/null +++ b/test-integ/connect/snapshot_test.go @@ -0,0 +1,212 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package connect + +import ( + "fmt" + "io" + "net/http" + "net/url" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" + "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" + "github.com/hashicorp/consul/testing/deployer/topology" +) + +// Test_Snapshot_Restore_Agentless verifies consul agent can continue +// to push envoy confgi after restoring from a snapshot. +// +// - This test is to detect server agent frozen after restoring from a snapshot +// (https://github.com/hashicorp/consul/pull/18636) +// +// - This bug only appeared in agentless mode +// +// Steps: +// 1. The test spins up a one-server cluster with static-server and static-client. +// 2. A snapshot is taken and the cluster is restored from the snapshot +// 3. A new static-server replaces the old one +// 4. At the end, we assert the static-client's upstream is updated with the +// new static-server +func Test_Snapshot_Restore_Agentless(t *testing.T) { + t.Parallel() + + staticServerSID := topology.NewServiceID("static-server", "default", "default") + staticClientSID := topology.NewServiceID("static-client", "default", "default") + + clu := &topology.Config{ + Images: utils.TargetImages(), + Networks: []*topology.Network{ + {Name: "dc1"}, + }, + Clusters: []*topology.Cluster{ + { + Name: "dc1", + Nodes: []*topology.Node{ + { + Kind: topology.NodeKindServer, + // NOTE: uncomment the following lines to trigger the agent frozen bug + // Images: topology.Images{ + // ConsulEnterprise: "hashicorp/consul-enterprise:1.16.1-ent", + // }, + Name: "dc1-server1", + Addresses: []*topology.Address{ + {Network: "dc1"}, + }, + }, + { + Kind: topology.NodeKindDataplane, + Name: "dc1-client1", + Services: []*topology.Service{ + { + ID: staticServerSID, + Image: "docker.mirror.hashicorp.services/fortio/fortio", + Port: 8080, + EnvoyAdminPort: 19000, + CheckTCP: "127.0.0.1:8080", + Command: []string{ + "server", + "-http-port", "8080", + "-redirect-port", "-disabled", + }, + }, + }, + }, + { + Kind: topology.NodeKindDataplane, + Name: "dc1-client2", + Services: []*topology.Service{ + { + ID: staticClientSID, + Image: "docker.mirror.hashicorp.services/fortio/fortio", + Port: 8080, + EnvoyAdminPort: 19000, + CheckTCP: "127.0.0.1:8080", + Command: []string{ + "server", + "-http-port", "8080", + "-redirect-port", "-disabled", + }, + Upstreams: []*topology.Upstream{ + { + ID: staticServerSID, + LocalPort: 5000, + }, + }, + }, + }, + }, + // Client3 for second static-server + { + Kind: topology.NodeKindDataplane, + Name: "dc1-client3", + Disabled: true, + Services: []*topology.Service{ + { + ID: staticServerSID, + Image: "docker.mirror.hashicorp.services/fortio/fortio", + Port: 8080, + EnvoyAdminPort: 19000, + CheckTCP: "127.0.0.1:8080", + Command: []string{ + "server", + "-http-port", "8080", + "-redirect-port", "-disabled", + }, + }, + }, + }, + }, + Enterprise: utils.IsEnterprise(), + InitialConfigEntries: []api.ConfigEntry{ + &api.ProxyConfigEntry{ + Kind: api.ProxyDefaults, + Name: "global", + Config: map[string]any{ + "protocol": "http", + }, + }, + &api.ServiceConfigEntry{ + Kind: api.ServiceDefaults, + Name: "static-server", + }, + &api.ServiceIntentionsConfigEntry{ + Kind: api.ServiceIntentions, + Name: "static-server", + Sources: []*api.SourceIntention{ + { + Name: "static-client", + Action: api.IntentionActionAllow, + }, + }, + }, + }, + }, + }, + } + sp := sprawltest.Launch(t, clu) + + client, err := sp.HTTPClientForCluster("dc1") + require.NoError(t, err) + + staticClient := sp.Topology().Clusters["dc1"].ServiceByID( + topology.NewNodeID("dc1-client2", "default"), + staticClientSID, + ) + staticClientAddress := fmt.Sprintf("%s:%d", staticClient.Node.LocalAddress(), staticClient.Port) + + // The following url causes the static-client's fortio server to + // fetch the ?url= param (the upstream static-server in our case). + url := fmt.Sprintf("http://%s/fortio/fetch2?url=%s", staticClientAddress, + url.QueryEscape("http://localhost:5000"), + ) + + // We retry the first request until we get 200 OK since it may take a while + // for the server to be available. + // Use a custom retry.Timer since the default one usually times out too early. + retrySendRequest := func(isSuccess bool) { + t.Log("static-client sending requests to static-server...") + retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { + resp, err := client.Post(url, "text/plain", nil) + require.NoError(r, err) + defer resp.Body.Close() + + if isSuccess { + require.Equal(r, http.StatusOK, resp.StatusCode) + } else { + require.NotEqual(r, http.StatusOK, resp.StatusCode) + } + body, err := io.ReadAll(resp.Body) + require.NoError(r, err) + fmt.Println("Body: ", string(body), resp.StatusCode) + }) + } + retrySendRequest(true) + t.Log("...ok, got 200 responses") + + t.Log("Take a snapshot of the cluster and restore ...") + err = sp.SnapshotSave("dc1") + require.NoError(t, err) + + // Shutdown existing static-server + cfg := sp.Config() + cluster := cfg.Cluster("dc1") + cluster.Nodes[1].Disabled = true // client 1 -- static-server + require.NoError(t, sp.Relaunch(cfg)) + retrySendRequest(false) + + // Add a new static-server + cfg = sp.Config() + cluster = cfg.Cluster("dc1") + cluster.Nodes[3].Disabled = false // client 3 -- static-server + require.NoError(t, sp.Relaunch(cfg)) + + // Ensure the static-client connected to static-server + retrySendRequest(true) +} diff --git a/test-integ/go.mod b/test-integ/go.mod index f86dfd043330..73b8dc62d80a 100644 --- a/test-integ/go.mod +++ b/test-integ/go.mod @@ -3,8 +3,9 @@ module github.com/hashicorp/consul/test-integ go 1.20 require ( - github.com/hashicorp/consul/api v1.24.0 - github.com/hashicorp/consul/sdk v0.14.1 + github.com/hashicorp/consul/api v1.26.1 + github.com/hashicorp/consul/proto-public v0.5.1 + github.com/hashicorp/consul/sdk v0.15.0 github.com/hashicorp/consul/test/integration/consul-container v0.0.0-20230628201853-bdf4fad7c5a5 github.com/hashicorp/consul/testing/deployer v0.0.0-20230811171106-4a0afb5d1373 github.com/hashicorp/go-cleanhttp v0.5.2 @@ -57,8 +58,8 @@ require ( 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-0.20230524094728-9239064ad72f // indirect - github.com/envoyproxy/protoc-gen-validate v0.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 @@ -93,8 +94,8 @@ require ( 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/envoyextensions v0.4.1 // indirect - github.com/hashicorp/consul/proto-public v0.4.1 // 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 @@ -104,6 +105,7 @@ require ( 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 @@ -127,7 +129,7 @@ require ( 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.3.0 // 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 @@ -176,7 +178,7 @@ require ( 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.3.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 @@ -203,15 +205,15 @@ require ( 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.12.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.14.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.11.0 // indirect - golang.org/x/term v0.11.0 // indirect - golang.org/x/text v0.12.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 @@ -219,7 +221,7 @@ require ( 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.0 // 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 diff --git a/test-integ/go.sum b/test-integ/go.sum index e5edc4188f32..09543e235cc2 100644 --- a/test-integ/go.sum +++ b/test-integ/go.sum @@ -182,11 +182,11 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= -github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= +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 v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= -github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +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= @@ -395,6 +395,8 @@ github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 h1:1ZEjnv 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= @@ -429,6 +431,8 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-netaddrs v0.1.0 h1:TnlYvODD4C/wO+j7cX1z69kV5gOzI87u3OcUinANaW8= +github.com/hashicorp/go-netaddrs v0.1.0/go.mod h1:33+a/emi5R5dqRspOuZKO0E+Tuz5WV1F84eRWALkedA= github.com/hashicorp/go-plugin v1.4.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= @@ -498,8 +502,8 @@ github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qR 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.3.0 h1:Mi6RPoRbsxIIYZryI+bSTXHD97Ua6rIYO51ibYV9bkY= -github.com/hashicorp/raft-wal v0.3.0/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= +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= @@ -698,8 +702,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: 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.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +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= @@ -843,8 +847,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y 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.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +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= @@ -932,8 +936,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx 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.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +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= @@ -1040,13 +1044,13 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc 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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.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.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +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= @@ -1058,8 +1062,8 @@ 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.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +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= @@ -1266,8 +1270,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K 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.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +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= diff --git a/test-integ/peering_commontopo/ac1_basic_test.go b/test-integ/peering_commontopo/ac1_basic_test.go index 85aaee4e6b55..ae729732e745 100644 --- a/test-integ/peering_commontopo/ac1_basic_test.go +++ b/test-integ/peering_commontopo/ac1_basic_test.go @@ -232,8 +232,6 @@ func (s *ac1BasicSuite) test(t *testing.T, ct *commonTopo) { // probably not worth the speed boost ct.Assert.HealthyWithPeer(t, dc.Name, svcServerHTTP.ID, LocalPeerName(peer, "default")) ct.Assert.HealthyWithPeer(t, dc.Name, svcServerTCP.ID, LocalPeerName(peer, "default")) - ct.Assert.UpstreamEndpointHealthy(t, svcClientTCP, ac.upstreamTCP) - ct.Assert.UpstreamEndpointHealthy(t, svcClientTCP, ac.upstreamHTTP) tcs := []struct { acSub int diff --git a/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go b/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go index 586103c11127..770e0ff90cc8 100644 --- a/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go +++ b/test-integ/peering_commontopo/ac3_service_defaults_upstream_test.go @@ -11,14 +11,13 @@ import ( "testing" "time" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/sdk/testutil/retry" + libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" "github.com/hashicorp/consul/testing/deployer/topology" "github.com/hashicorp/go-cleanhttp" "github.com/itchyny/gojq" "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" ) var ac3SvcDefaultsSuites []sharedTopoSuite = []sharedTopoSuite{ @@ -173,7 +172,6 @@ func (s *ac3SvcDefaultsSuite) test(t *testing.T, ct *commonTopo) { // these could be done parallel with each other, but complexity // probably not worth the speed boost ct.Assert.HealthyWithPeer(t, dc.Name, svcServer.ID, LocalPeerName(peer, "default")) - ct.Assert.UpstreamEndpointHealthy(t, svcClient, s.upstream) // TODO: we need to let the upstream start serving properly before we do this. if it // isn't ready and returns a 5xx (which it will do if it's not up yet!), it will stick // in a down state for PassiveHealthCheck.Interval @@ -185,7 +183,7 @@ func (s *ac3SvcDefaultsSuite) test(t *testing.T, ct *commonTopo) { // TODO: what is default? namespace? partition? clusterName := fmt.Sprintf("%s.default.%s.external", s.upstream.ID.Name, s.upstream.Peer) nonceStatus := http.StatusInsufficientStorage - url507 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", svcClient.ExposedPort, + url507 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", svcClient.ExposedPort(""), url.QueryEscape(fmt.Sprintf("http://localhost:%d/?status=%d", s.upstream.LocalPort, nonceStatus)), ) @@ -221,7 +219,7 @@ func (s *ac3SvcDefaultsSuite) test(t *testing.T, ct *commonTopo) { require.True(r, resultAsBool) }) - url200 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", svcClient.ExposedPort, + url200 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", svcClient.ExposedPort(""), url.QueryEscape(fmt.Sprintf("http://localhost:%d/", s.upstream.LocalPort)), ) retry.RunWith(&retry.Timer{Timeout: time.Minute * 1, Wait: time.Millisecond * 500}, t, func(r *retry.R) { diff --git a/test-integ/peering_commontopo/ac4_proxy_defaults_test.go b/test-integ/peering_commontopo/ac4_proxy_defaults_test.go index c413820c6f2b..28df1c3d4c67 100644 --- a/test-integ/peering_commontopo/ac4_proxy_defaults_test.go +++ b/test-integ/peering_commontopo/ac4_proxy_defaults_test.go @@ -159,7 +159,6 @@ func (s *ac4ProxyDefaultsSuite) test(t *testing.T, ct *commonTopo) { // preconditions check ct.Assert.HealthyWithPeer(t, dc.Name, serverSVC.ID, LocalPeerName(peer, "default")) - ct.Assert.UpstreamEndpointHealthy(t, clientSVC, s.upstream) ct.Assert.FortioFetch2HeaderEcho(t, clientSVC, s.upstream) t.Run("Validate services exist in catalog", func(t *testing.T) { @@ -180,11 +179,11 @@ func (s *ac4ProxyDefaultsSuite) test(t *testing.T, ct *commonTopo) { }) t.Run("HTTP service fails due to connection timeout", func(t *testing.T) { - url504 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", client.ExposedPort, + url504 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", client.ExposedPort(""), url.QueryEscape(fmt.Sprintf("http://localhost:%d/?delay=1000ms", s.upstream.LocalPort)), ) - url200 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", client.ExposedPort, + url200 := fmt.Sprintf("http://localhost:%d/fortio/fetch2?url=%s", client.ExposedPort(""), url.QueryEscape(fmt.Sprintf("http://localhost:%d/", s.upstream.LocalPort)), ) diff --git a/test-integ/peering_commontopo/ac5_2_pq_failover_test.go b/test-integ/peering_commontopo/ac5_2_pq_failover_test.go index 3bf8c9be9ac8..dec0de3ea1f9 100644 --- a/test-integ/peering_commontopo/ac5_2_pq_failover_test.go +++ b/test-integ/peering_commontopo/ac5_2_pq_failover_test.go @@ -30,11 +30,15 @@ type ac5_2PQFailoverSuite struct { serverSID topology.ServiceID nodeServer topology.NodeID } +type nodeKey struct { + dc string + partition string +} var ac5_2Context = make(map[nodeKey]ac5_2PQFailoverSuite) func TestAC5PreparedQueryFailover(t *testing.T) { - ct := NewCommonTopo(t) + ct := newCommonTopo(t, "dc2", true, true) s := &ac5_2PQFailoverSuite{} s.setup(t, ct) ct.Launch(t) diff --git a/test-integ/peering_commontopo/ac6_failovers_test.go b/test-integ/peering_commontopo/ac6_failovers_test.go index fe3cd181b203..25e734200f36 100644 --- a/test-integ/peering_commontopo/ac6_failovers_test.go +++ b/test-integ/peering_commontopo/ac6_failovers_test.go @@ -14,419 +14,453 @@ import ( "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) -// note: unlike other *Suite structs that are per-peering direction, -// this one is special and does all directions itself, because the -// setup is not exactly symmetrical type ac6FailoversSuite struct { - ac6 map[nodeKey]ac6FailoversContext -} -type ac6FailoversContext struct { + // inputs + // with all false, this gives us a scenario with: + // - a "near" server in the accepter cluster (DC1), partitition default, namespace default + // - a "far" server in the dialer cluster (DC2), partition default, namespace default + // - a client in the accepter cluster (DC1), partition default, namespace default, with: + // - upstream near server (DC1) + // - failover to far server (DC2) + // + // TODO: technically if NearInDial && !FarInAcc (i.e., near == far), then we're not doing peering at all, + // and could do this test in a single DC + + // when true, put the client (and its default upstream server) in the dialer peer; otherwise, put client in accepter + NearInDial bool + // when true, put the client (and its default upstream server) in the nondefault partition/namespace; otherwise in the default + NearInPartAlt bool + NearInNSAlt bool + // when true, put far server to the accepter peer; otherwise the dialer + FarInAcc bool + // when true, put far server to nondefault partition/namespace (ENT-only); otherwise, failover to default + FarInPartAlt bool + FarInNSAlt bool + + // launch outputs, for querying during test clientSID topology.ServiceID - serverSID topology.ServiceID - + // near = same DC as client; far = other DC + nearServerSID topology.ServiceID // used to remove the node and trigger failover - serverNode topology.NodeID -} -type nodeKey struct { - dc string - partition string + nearServerNode topology.NodeID + farServerSID topology.ServiceID + farServerNode topology.NodeID } // Note: this test cannot share topo func TestAC6Failovers(t *testing.T) { - ct := NewCommonTopo(t) - s := &ac6FailoversSuite{} - s.setup(t, ct) - ct.Launch(t) - s.test(t, ct) + // bit banging to get all permutations of all params + const nParams = 3 + // i.e 2**nParams + const n = int(1) << nParams + for i := 0; i < n; i++ { + s := ac6FailoversSuite{ + // xth bit == 1 + NearInDial: (i>>0)&1 == 1, + NearInPartAlt: (i>>1)&1 == 1, + FarInPartAlt: (i>>2)&1 == 1, + } + // ensure the servers are always in separate DCs + s.FarInAcc = s.NearInDial + t.Run(fmt.Sprintf("%02d_%s", i, s.testName()), func(t *testing.T) { + t.Parallel() + ct := NewCommonTopo(t) + s.setup(t, ct) + ct.Launch(t) + s.test(t, ct) + }) + } } -func (s *ac6FailoversSuite) setup(t *testing.T, ct *commonTopo) { - // TODO: update setups to loop through a cluster's partitions+namespaces internally - s.setupAC6Failovers(ct, ct.DC1, ct.DC2) - s.setupAC6Failovers(ct, ct.DC2, ct.DC1) - s.setupAC6FailoversDC3(ct, ct.DC3, ct.DC1, ct.DC2) +func TestNET5029Failovers(t *testing.T) { + // TODO: *.{a,b} are not actually peering tests, and should technically be moved elsewhere + suites := map[string]ac6FailoversSuite{ + "1.a": { + FarInAcc: true, + FarInPartAlt: true, + }, + "1.b": { + FarInAcc: true, + FarInNSAlt: true, + }, + "1.c": { + FarInNSAlt: true, + }, + "1.d": { + FarInPartAlt: true, + }, + "2.a": { + FarInAcc: true, + NearInPartAlt: true, + }, + "2.b": { + FarInAcc: true, + NearInNSAlt: true, + }, + "2.c": { + NearInDial: true, + NearInNSAlt: true, + FarInAcc: true, + }, + "2.d": { + NearInDial: true, + NearInPartAlt: true, + FarInAcc: true, + }, + } + for name, s := range suites { + s := s + t.Run(fmt.Sprintf("%s_%s", name, s.testName()), func(t *testing.T) { + if name == "1.b" { + t.Skip("TODO: fails with 503/504") + } + t.Parallel() + ct := NewCommonTopo(t) + s.setup(t, ct) + ct.Launch(t) + s.test(t, ct) + }) + } } -// dc1 is peered with dc2 and dc3. -// dc1 has an ac6-client in "default" and "part1" partitions (only default in CE). -// ac6-client has a single upstream ac6-failover-svc in its respective partition^. -// -// ac6-failover-svc has the following failovers: -// - peer-dc2-default -// - peer-dc2-part1 (not in CE) -// - peer-dc3-default -// -// This setup is mirrored from dc2->dc1 as well -// (both dcs have dc3 as the last failover target) -// -// ^NOTE: There are no cross-partition upstreams because MeshGatewayMode = local -// and failover information gets stripped out by the mesh gateways so we -// can't test failovers. -func (s *ac6FailoversSuite) setupAC6Failovers(ct *commonTopo, clu, peerClu *topology.Cluster) { - for _, part := range clu.Partitions { - partition := part.Name - - // There is a peering per partition in the peered cluster - var peers []string - for _, peerPart := range peerClu.Partitions { - peers = append(peers, LocalPeerName(peerClu, peerPart.Name)) +func TestAC6Failovers_AllPermutations(t *testing.T) { + // + t.Skip("Too many permutations") + // bit banging to get all permutations of all params + const nParams = 6 + // i.e 2**nParams + const n = int(1) << nParams + for i := 0; i < n; i++ { + s := ac6FailoversSuite{ + // xth bit == 1 + NearInDial: (i>>0)&1 == 1, + FarInAcc: (i>>1)&1 == 1, + NearInPartAlt: (i>>2)&1 == 1, + FarInPartAlt: (i>>3)&1 == 1, + NearInNSAlt: (i>>4)&1 == 1, + FarInNSAlt: (i>>5)&1 == 1, } + t.Run(fmt.Sprintf("%02d_%s", i, s.testName()), func(t *testing.T) { + t.Parallel() + ct := NewCommonTopo(t) + s.setup(t, ct) + ct.Launch(t) + s.test(t, ct) + }) + } +} - // Make an HTTP server with various failover targets - serverSID := topology.ServiceID{ - Name: "ac6-failover-svc", - Partition: partition, - } - server := NewFortioServiceWithDefaults( - clu.Datacenter, - serverSID, - nil, - ) - // Export to all known peers - ct.ExportService(clu, partition, +func (s *ac6FailoversSuite) testName() (ret string) { + switch s.NearInDial { + case true: + ret += "dial" + default: + ret += "acc" + } + ret += "." + switch s.NearInPartAlt { + case true: + ret += "alt" + default: + ret += "default" + } + ret += "." + switch s.NearInNSAlt { + case true: + ret += "alt" + default: + ret += "default" + } + + ret += "->" + + switch s.FarInAcc { + case true: + ret += "acc" + default: + ret += "dial" + } + ret += "." + switch s.FarInPartAlt { + case true: + ret += "alt" + default: + ret += "default" + } + ret += "." + switch s.FarInNSAlt { + case true: + ret += "alt" + default: + ret += "default" + } + + return +} + +func (s *ac6FailoversSuite) setup(t *testing.T, ct *commonTopo) { + if !utils.IsEnterprise() && (s.NearInPartAlt || s.FarInPartAlt) { + t.Skip("ENT required for nondefault partitions") + } + + nearClu := ct.DC1 + farClu := ct.DC2 + if s.NearInDial { + nearClu = ct.DC2 + } + if s.FarInAcc { + farClu = ct.DC1 + } + + // - server in clientPartition/DC (main target) + nearServerSID := topology.ServiceID{ + Name: "ac6-server", + Partition: ConfigEntryPartition("default"), + Namespace: "default", + } + if s.NearInPartAlt { + nearServerSID.Partition = "part1" + } + if s.NearInNSAlt { + nearServerSID.Namespace = "ns1" + } + nearServer := NewFortioServiceWithDefaults( + nearClu.Datacenter, + nearServerSID, + nil, + ) + nearServerNode := ct.AddServiceNode(nearClu, serviceExt{Service: nearServer}) + + nearClu.InitialConfigEntries = append(nearClu.InitialConfigEntries, + &api.ServiceConfigEntry{ + Kind: api.ServiceDefaults, + Name: nearServerSID.Name, + Partition: ConfigEntryPartition(nearServerSID.Partition), + Namespace: nearServerSID.Namespace, + Protocol: "http", + }, + ) + // - server in otherPartition/otherDC + farServerSID := topology.ServiceID{ + Name: nearServerSID.Name, + Partition: "default", + Namespace: "default", + } + if s.FarInPartAlt { + farServerSID.Partition = "part1" + } + if s.FarInNSAlt { + farServerSID.Namespace = "ns1" + } + farServer := NewFortioServiceWithDefaults( + farClu.Datacenter, + farServerSID, + nil, + ) + farServerNode := ct.AddServiceNode(farClu, serviceExt{Service: farServer}) + if nearClu != farClu { + ct.ExportService(farClu, farServerSID.Partition, api.ExportedService{ - Name: server.ID.Name, - Consumers: func() []api.ServiceConsumer { - var consumers []api.ServiceConsumer - for _, peer := range peers { - consumers = append(consumers, api.ServiceConsumer{ - Peer: peer, - }) - } - return consumers - }(), - }, - ) - serverNode := ct.AddServiceNode(clu, serviceExt{Service: server}) - - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", - }, - &api.ServiceResolverConfigEntry{ - Kind: api.ServiceResolver, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Failover: map[string]api.ServiceResolverFailover{ - "*": { - Targets: func() []api.ServiceResolverFailoverTarget { - // Make a failover target for every partition in the peer cluster - var targets []api.ServiceResolverFailoverTarget - for _, peer := range peers { - targets = append(targets, api.ServiceResolverFailoverTarget{ - Peer: peer, - }) - } - // Just hard code default partition for dc3, since the exhaustive - // testing will be done against dc2. - targets = append(targets, api.ServiceResolverFailoverTarget{ - Peer: "peer-dc3-default", - }) - return targets - }(), + Name: farServerSID.Name, + Namespace: farServerSID.Namespace, + Consumers: []api.ServiceConsumer{ + { + Peer: LocalPeerName(nearClu, nearServerSID.Partition), }, }, }, ) - - // Make client which will dial server - clientSID := topology.ServiceID{ - Name: "ac6-client", - Partition: partition, - } - client := NewFortioServiceWithDefaults( - clu.Datacenter, - clientSID, - func(s *topology.Service) { - // Upstream per partition - s.Upstreams = []*topology.Upstream{ + } else if nearClu == farClu && farServerSID.Partition != nearServerSID.Partition { + ct.ExportService(farClu, farServerSID.Partition, + api.ExportedService{ + Name: farServerSID.Name, + Namespace: farServerSID.Namespace, + Consumers: []api.ServiceConsumer{ { - ID: topology.ServiceID{ - Name: server.ID.Name, - Partition: part.Name, - }, - LocalPort: 5000, - // exposed so we can hit it directly - // TODO: we shouldn't do this; it's not realistic - LocalAddress: "0.0.0.0", + // this must not be "", or else it is basically ignored altogether + // TODO: bug? if this whole struct is empty, that should be an error + Partition: topology.PartitionOrDefault(nearServerSID.Partition), }, - } - }, - ) - ct.ExportService(clu, partition, - api.ExportedService{ - Name: client.ID.Name, - Consumers: func() []api.ServiceConsumer { - var consumers []api.ServiceConsumer - // Export to each peer - for _, peer := range peers { - consumers = append(consumers, api.ServiceConsumer{ - Peer: peer, - }) - } - return consumers - }(), - }, - ) - ct.AddServiceNode(clu, serviceExt{Service: client}) - - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceConfigEntry{ - Kind: api.ServiceDefaults, - Name: client.ID.Name, - Partition: ConfigEntryPartition(partition), - Protocol: "http", + }, }, ) + } - // Add intention allowing local and peered clients to call server - clu.InitialConfigEntries = append(clu.InitialConfigEntries, - &api.ServiceIntentionsConfigEntry{ - Kind: api.ServiceIntentions, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - // SourceIntention for local client and peered clients - Sources: func() []*api.SourceIntention { - ixns := []*api.SourceIntention{ - { - Name: client.ID.Name, - Partition: ConfigEntryPartition(part.Name), - Action: api.IntentionActionAllow, - }, - } - for _, peer := range peers { - ixns = append(ixns, &api.SourceIntention{ - Name: client.ID.Name, - Peer: peer, - Action: api.IntentionActionAllow, - }) - } - return ixns - }(), + var targets []api.ServiceResolverFailoverTarget + if nearClu != farClu { + targets = []api.ServiceResolverFailoverTarget{ + { + Service: farServerSID.Name, + Peer: LocalPeerName(farClu, farServerSID.Partition), + Namespace: farServerSID.Namespace, }, - ) - if s.ac6 == nil { - s.ac6 = map[nodeKey]ac6FailoversContext{} } - s.ac6[nodeKey{clu.Datacenter, partition}] = struct { - clientSID topology.ServiceID - serverSID topology.ServiceID - serverNode topology.NodeID - }{ - clientSID: clientSID, - serverSID: serverSID, - serverNode: serverNode.ID(), + } else { + part := ConfigEntryPartition(farServerSID.Partition) + // weird exception here where target partition set to "" means "inherit from parent" + // TODO: bug? docs say "" -> default: + // https://developer.hashicorp.com/consul/docs/connect/config-entries/service-resolver#failover-targets-partition + if farServerSID.Partition == "default" && nearServerSID.Partition != "default" { + part = "default" + } + targets = []api.ServiceResolverFailoverTarget{ + { + Service: farServerSID.Name, + Partition: part, + Namespace: farServerSID.Namespace, + }, } - } -} - -func (s *ac6FailoversSuite) setupAC6FailoversDC3(ct *commonTopo, clu, peer1, peer2 *topology.Cluster) { - var peers []string - for _, part := range peer1.Partitions { - peers = append(peers, LocalPeerName(peer1, part.Name)) - } - for _, part := range peer2.Partitions { - peers = append(peers, LocalPeerName(peer2, part.Name)) } - partition := "default" - - // Make an HTTP server - server := NewFortioServiceWithDefaults( - clu.Datacenter, - topology.ServiceID{ - Name: "ac6-failover-svc", - Partition: partition, + nearClu.InitialConfigEntries = append(nearClu.InitialConfigEntries, + &api.ServiceConfigEntry{ + Kind: api.ServiceDefaults, + Name: farServerSID.Name, + Partition: ConfigEntryPartition(farServerSID.Partition), + Namespace: farServerSID.Namespace, + Protocol: "http", + }, + &api.ServiceResolverConfigEntry{ + Kind: api.ServiceResolver, + Name: nearServerSID.Name, + Partition: ConfigEntryPartition(nearServerSID.Partition), + Namespace: nearServerSID.Namespace, + Failover: map[string]api.ServiceResolverFailover{ + "*": { + Targets: targets, + }, + }, }, - nil, ) - ct.AddServiceNode(clu, serviceExt{ - Service: server, - Config: &api.ServiceConfigEntry{ + clientSID := topology.ServiceID{ + Name: "ac6-client", + Partition: nearServerSID.Partition, + Namespace: nearServerSID.Namespace, + } + client := NewFortioServiceWithDefaults( + nearClu.Datacenter, + clientSID, + func(s *topology.Service) { + // Upstream per partition + s.Upstreams = []*topology.Upstream{ + { + ID: topology.ServiceID{ + Name: nearServerSID.Name, + Partition: nearServerSID.Partition, + Namespace: nearServerSID.Namespace, + }, + LocalPort: 5000, + // exposed so we can hit it directly + // TODO: we shouldn't do this; it's not realistic + LocalAddress: "0.0.0.0", + }, + } + }, + ) + ct.AddServiceNode(nearClu, serviceExt{Service: client}) + nearClu.InitialConfigEntries = append(nearClu.InitialConfigEntries, + &api.ServiceConfigEntry{ Kind: api.ServiceDefaults, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), + Name: clientSID.Name, + Partition: ConfigEntryPartition(clientSID.Partition), + Namespace: clientSID.Namespace, Protocol: "http", }, - Intentions: &api.ServiceIntentionsConfigEntry{ + ) + + // intentions + nearClu.InitialConfigEntries = append(nearClu.InitialConfigEntries, + &api.ServiceIntentionsConfigEntry{ Kind: api.ServiceIntentions, - Name: server.ID.Name, - Partition: ConfigEntryPartition(partition), - Sources: func() []*api.SourceIntention { - var ixns []*api.SourceIntention - for _, peer := range peers { - ixns = append(ixns, &api.SourceIntention{ - Name: "ac6-client", - Peer: peer, - Action: api.IntentionActionAllow, - }) - } - return ixns - }(), + Name: nearServerSID.Name, + Partition: ConfigEntryPartition(nearServerSID.Partition), + Namespace: nearServerSID.Namespace, + Sources: []*api.SourceIntention{{ + Name: clientSID.Name, + Namespace: clientSID.Namespace, + // in this field, "" -> destination partition, so no ConfigEntryPartition :eyeroll: + // https://developer.hashicorp.com/consul/docs/connect/config-entries/service-intentions#sources-partition + Partition: topology.PartitionOrDefault(clientSID.Partition), + Action: api.IntentionActionAllow, + }}, }, - Exports: func() []api.ServiceConsumer { - var consumers []api.ServiceConsumer - for _, peer := range peers { - consumers = append(consumers, api.ServiceConsumer{ - Peer: peer, - }) - } - return consumers - }(), - }) + ) + farSource := api.SourceIntention{ + Name: clientSID.Name, + Namespace: clientSID.Namespace, + Peer: LocalPeerName(nearClu, clientSID.Partition), + Action: api.IntentionActionAllow, + } + if nearClu == farClu { + farSource.Peer = "" + // in this field, "" -> destination partition, so no ConfigEntryPartition :eyeroll: + // https://developer.hashicorp.com/consul/docs/connect/config-entries/service-intentions#sources-partition + farSource.Partition = topology.PartitionOrDefault(clientSID.Partition) + } + farClu.InitialConfigEntries = append(farClu.InitialConfigEntries, + &api.ServiceIntentionsConfigEntry{ + Kind: api.ServiceIntentions, + Name: farServerSID.Name, + Partition: ConfigEntryPartition(farServerSID.Partition), + Namespace: farServerSID.Namespace, + Sources: []*api.SourceIntention{&farSource}, + }, + ) + + s.clientSID = clientSID + s.nearServerSID = nearServerSID + s.farServerSID = farServerSID + s.nearServerNode = nearServerNode.ID() + s.farServerNode = farServerNode.ID() } func (s *ac6FailoversSuite) test(t *testing.T, ct *commonTopo) { - dc1 := ct.Sprawl.Topology().Clusters["dc1"] - dc2 := ct.Sprawl.Topology().Clusters["dc2"] - - type testcase struct { - name string - cluster *topology.Cluster - peer *topology.Cluster - partition string + // NOTE: *not parallel* because we mutate resources that are shared + // between test cases (disable/enable nodes) + + nearClu := ct.Sprawl.Topology().Clusters["dc1"] + farClu := ct.Sprawl.Topology().Clusters["dc2"] + if s.NearInDial { + nearClu = ct.Sprawl.Topology().Clusters["dc2"] } - tcs := []testcase{ - { - name: "dc1 default partition failovers", - cluster: dc1, - peer: dc2, // dc3 is hardcoded - partition: "default", - }, - { - name: "dc1 part1 partition failovers", - cluster: dc1, - peer: dc2, // dc3 is hardcoded - partition: "part1", - }, - { - name: "dc2 default partition failovers", - cluster: dc2, - peer: dc1, // dc3 is hardcoded - partition: "default", - }, - { - name: "dc2 part1 partition failovers", - cluster: dc2, - peer: dc1, // dc3 is hardcoded - partition: "part1", - }, + if s.FarInAcc { + farClu = ct.Sprawl.Topology().Clusters["dc1"] } - for _, tc := range tcs { - t.Run(tc.name, func(t *testing.T) { - // NOTE: *not parallel* because we mutate resources that are shared - // between test cases (disable/enable nodes) - if !utils.IsEnterprise() && tc.partition != "default" { - t.Skip("skipping enterprise test") - } - partition := tc.partition - clu := tc.cluster - peerClu := tc.peer - - svcs := clu.ServicesByID(s.ac6[nodeKey{clu.Datacenter, partition}].clientSID) - require.Len(t, svcs, 1, "expected exactly one client in datacenter") - - serverSID := s.ac6[nodeKey{clu.Datacenter, partition}].serverSID - serverSID.Normalize() - - client := svcs[0] - require.Len(t, client.Upstreams, 1, "expected one upstream for client") - - u := client.Upstreams[0] - ct.Assert.CatalogServiceExists(t, clu.Name, u.ID.Name, utils.CompatQueryOpts(&api.QueryOptions{ - Partition: u.ID.Partition, - })) - - t.Cleanup(func() { - cfg := ct.Sprawl.Config() - for _, part := range clu.Partitions { - EnableNode(t, cfg, clu.Name, s.ac6[nodeKey{clu.Datacenter, part.Name}].serverNode) - } - for _, part := range peerClu.Partitions { - EnableNode(t, cfg, peerClu.Name, s.ac6[nodeKey{peerClu.Datacenter, part.Name}].serverNode) - } - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - }) - - fmt.Println("### preconditions") - // TODO: deduce this number, instead of hard-coding - nFailoverTargets := 4 - // in CE, we don't have failover targets for non-default partitions - if !utils.IsEnterprise() { - nFailoverTargets = 3 - } - for i := 0; i < nFailoverTargets; i++ { - ct.Assert.UpstreamEndpointStatus(t, client, fmt.Sprintf("failover-target~%d~%s", i, clusterPrefix(u, clu.Datacenter)), "HEALTHY", 1) - } - ct.Assert.FortioFetch2FortioName(t, client, u, clu.Name, serverSID) + svcs := nearClu.ServicesByID(s.clientSID) + require.Len(t, svcs, 1, "expected exactly one client in datacenter") - if t.Failed() { - t.Fatalf("failed preconditions") - } + client := svcs[0] + require.Len(t, client.Upstreams, 1, "expected one upstream for client") + upstream := client.Upstreams[0] - fmt.Println("### Failover to peer target") - cfg := ct.Sprawl.Config() - DisableNode(t, cfg, clu.Name, s.ac6[nodeKey{clu.Datacenter, partition}].serverNode) - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - // Clusters for imported services rely on outlier detection for - // failovers, NOT eds_health_status. This means that killing the - // node above does not actually make the envoy cluster UNHEALTHY - // so we do not assert for it. - expectUID := topology.ServiceID{ - Name: u.ID.Name, - Partition: "default", - } - expectUID.Normalize() - ct.Assert.FortioFetch2FortioName(t, client, u, peerClu.Name, expectUID) - - if utils.IsEnterprise() { - fmt.Println("### Failover to peer target in non-default partition") - cfg = ct.Sprawl.Config() - DisableNode(t, cfg, clu.Name, s.ac6[nodeKey{clu.Datacenter, partition}].serverNode) - DisableNode(t, cfg, peerClu.Name, s.ac6[nodeKey{peerClu.Datacenter, "default"}].serverNode) - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - // Retry until outlier_detection deems the cluster - // unhealthy and fails over to peer part1. - expectUID = topology.ServiceID{ - Name: u.ID.Name, - Partition: "part1", - } - expectUID.Normalize() - ct.Assert.FortioFetch2FortioName(t, client, u, peerClu.Name, expectUID) - } + fmt.Println("### preconditions") - fmt.Println("### Failover to dc3 peer target") - cfg = ct.Sprawl.Config() - DisableNode(t, cfg, clu.Name, s.ac6[nodeKey{clu.Datacenter, partition}].serverNode) - // Disable all partitions for peer - for _, part := range peerClu.Partitions { - DisableNode(t, cfg, peerClu.Name, s.ac6[nodeKey{peerClu.Datacenter, part.Name}].serverNode) - } - require.NoError(t, ct.Sprawl.Relaunch(cfg)) - // This will retry until outlier_detection deems the cluster - // unhealthy and fails over to dc3. - expectUID = topology.ServiceID{ - Name: u.ID.Name, - Partition: "default", - } - expectUID.Normalize() - ct.Assert.FortioFetch2FortioName(t, client, u, "dc3", expectUID) - }) - } -} + // this is the server in the same DC and partitions as client + serverSID := s.nearServerSID + serverSID.Normalize() + ct.Assert.FortioFetch2FortioName(t, client, upstream, nearClu.Name, serverSID) -func clusterPrefix(u *topology.Upstream, dc string) string { - u.ID.Normalize() - switch u.ID.Partition { - case "default": - return fmt.Sprintf("%s.%s.%s.internal", u.ID.Name, u.ID.Namespace, dc) - default: - return fmt.Sprintf("%s.%s.%s.%s.internal-v1", u.ID.Name, u.ID.Namespace, u.ID.Partition, dc) + ct.Assert.CatalogServiceExists(t, nearClu.Name, upstream.ID.Name, utils.CompatQueryOpts(&api.QueryOptions{ + Partition: upstream.ID.Partition, + Namespace: upstream.ID.Namespace, + })) + + if t.Failed() { + t.Fatal("failed preconditions") } + + fmt.Println("### failover") + + cfg := ct.Sprawl.Config() + DisableNode(t, cfg, nearClu.Name, s.nearServerNode) + require.NoError(t, ct.Sprawl.RelaunchWithPhase(cfg, "failover")) + // Clusters for imported services rely on outlier detection for + // failovers, NOT eds_health_status. This means that killing the + // node above does not actually make the envoy cluster UNHEALTHY + // so we do not assert for it. + expectSID := s.farServerSID + expectSID.Normalize() + ct.Assert.FortioFetch2FortioName(t, client, upstream, farClu.Name, expectSID) } diff --git a/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go b/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go index 4973cb6d0487..a492b95dc05f 100644 --- a/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go +++ b/test-integ/peering_commontopo/ac7_1_rotate_gw_test.go @@ -8,10 +8,9 @@ import ( "strings" "testing" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/testing/deployer/topology" "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/api" ) // TestRotateGW ensures that peered services continue to be able to talk to their @@ -142,10 +141,10 @@ func (s *suiteRotateGW) setup(t *testing.T, ct *commonTopo) { // add a second mesh gateway "new" s.newMGWNodeName = fmt.Sprintf("new-%s-default-mgw", clu.Name) nodeKind := topology.NodeKindClient - if clu.Datacenter == agentlessDC { + if clu.Datacenter == ct.agentlessDC { nodeKind = topology.NodeKindDataplane } - clu.Nodes = append(clu.Nodes, newTopologyMeshGatewaySet( + _, mgwNodes := newTopologyMeshGatewaySet( nodeKind, "default", s.newMGWNodeName, @@ -154,7 +153,8 @@ func (s *suiteRotateGW) setup(t *testing.T, ct *commonTopo) { func(i int, node *topology.Node) { node.Disabled = true }, - )...) + ) + clu.Nodes = append(clu.Nodes, mgwNodes...) } func (s *suiteRotateGW) test(t *testing.T, ct *commonTopo) { diff --git a/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go b/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go index a5684ebbc024..36e3c0ced3f5 100644 --- a/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go +++ b/test-integ/peering_commontopo/ac7_2_rotate_leader_test.go @@ -8,12 +8,13 @@ import ( "testing" "time" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" - "github.com/hashicorp/consul/testing/deployer/topology" "github.com/mitchellh/copystructure" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" + "github.com/hashicorp/consul/testing/deployer/topology" + "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil/retry" ) @@ -165,7 +166,7 @@ func (s *ac7_2RotateLeaderSuite) test(t *testing.T, ct *commonTopo) { found := 0 foundI := 0 for i, svc := range ceAsES.Services { - if svc.Name == s.sidServer.Name && svc.Namespace == utils.DefaultToEmpty(s.sidServer.Namespace) { + if svc.Name == s.sidServer.Name && utils.DefaultToEmpty(svc.Namespace) == utils.DefaultToEmpty(s.sidServer.Namespace) { found += 1 foundI = i } @@ -176,7 +177,7 @@ func (s *ac7_2RotateLeaderSuite) test(t *testing.T, ct *commonTopo) { _, _, err = clPeer.ConfigEntries().Set(ceAsES, nil) require.NoError(t, err) t.Cleanup(func() { - //restore for next pairing + // restore for next pairing _, _, err = clPeer.ConfigEntries().Set(origCE.(*api.ExportedServicesConfigEntry), nil) require.NoError(t, err) }) diff --git a/test-integ/peering_commontopo/commontopo.go b/test-integ/peering_commontopo/commontopo.go index e43456b231bc..be2ae79cd64f 100644 --- a/test-integ/peering_commontopo/commontopo.go +++ b/test-integ/peering_commontopo/commontopo.go @@ -4,23 +4,21 @@ package peering import ( - "bytes" "context" "fmt" - "strconv" "testing" - "text/tabwriter" "time" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" "github.com/hashicorp/consul/testing/deployer/sprawl" "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" "github.com/hashicorp/consul/testing/deployer/topology" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" - "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" + "github.com/hashicorp/consul/test-integ/topoutil" ) // commonTopo helps create a shareable topology configured to represent @@ -42,74 +40,110 @@ type commonTopo struct { // shortcuts to corresponding entry in Cfg DC1 *topology.Cluster DC2 *topology.Cluster + // nil if includeDC3 is false DC3 *topology.Cluster // set after Launch. Should be considered read-only Sprawl *sprawl.Sprawl - Assert *asserter + Assert *topoutil.Asserter // track per-DC services to prevent duplicates services map[string]map[topology.ServiceID]struct{} + + // if zero, no DCs are agentless + agentlessDC string + + // if true, create DC3 and associated links (currently only used by ac5.2) + includeDC3 bool + + peerThroughMGW bool } -const agentlessDC = "dc2" +func NewCommonTopoWithoutAgentless(t *testing.T) *commonTopo { + t.Helper() + return newCommonTopo(t, "", false, true) +} func NewCommonTopo(t *testing.T) *commonTopo { t.Helper() + return newCommonTopo(t, "dc2", false, true) +} - ct := commonTopo{} +func newCommonTopo(t *testing.T, agentlessDC string, includeDC3 bool, peerThroughMGW bool) *commonTopo { + t.Helper() + + ct := commonTopo{ + agentlessDC: agentlessDC, + includeDC3: includeDC3, + peerThroughMGW: peerThroughMGW, + } const nServers = 3 // Make 3-server clusters in dc1 and dc2 // For simplicity, the Name and Datacenter of the clusters are the same. // dc1 and dc2 should be symmetric. - dc1 := clusterWithJustServers("dc1", nServers) + dc1 := ct.clusterWithJustServers("dc1", nServers) ct.DC1 = dc1 - dc2 := clusterWithJustServers("dc2", nServers) + dc2 := ct.clusterWithJustServers("dc2", nServers) ct.DC2 = dc2 - // dc3 is a failover cluster for both dc1 and dc2 - dc3 := clusterWithJustServers("dc3", 1) - // dc3 is only used for certain failover scenarios and does not need tenancies - dc3.Partitions = []*topology.Partition{{Name: "default"}} - ct.DC3 = dc3 + clusters := []*topology.Cluster{dc1, dc2} + + var dc3 *topology.Cluster + + if ct.includeDC3 { + // dc3 is a failover cluster for both dc1 and dc2 + dc3 = ct.clusterWithJustServers("dc3", 1) + // dc3 is only used for certain failover scenarios and does not need tenancies + dc3.Partitions = []*topology.Partition{{Name: "default"}} + ct.DC3 = dc3 + // dc3 is only used for certain failover scenarios and does not need tenancies + dc3.Partitions = []*topology.Partition{{Name: "default"}} + + clusters = append(clusters, dc3) + } injectTenancies(dc1) injectTenancies(dc2) - // dc3 is only used for certain failover scenarios and does not need tenancies - dc3.Partitions = []*topology.Partition{{Name: "default"}} + // dc3 doesn't get tenancies ct.services = map[string]map[topology.ServiceID]struct{}{} - for _, dc := range []*topology.Cluster{dc1, dc2, dc3} { + for _, dc := range clusters { ct.services[dc.Datacenter] = map[topology.ServiceID]struct{}{} } peerings := addPeerings(dc1, dc2) - peerings = append(peerings, addPeerings(dc1, dc3)...) - peerings = append(peerings, addPeerings(dc2, dc3)...) + if ct.includeDC3 { + peerings = append(peerings, addPeerings(dc1, dc3)...) + peerings = append(peerings, addPeerings(dc2, dc3)...) + } - addMeshGateways(dc1) - addMeshGateways(dc2) - addMeshGateways(dc3) + ct.addMeshGateways(dc1) + ct.addMeshGateways(dc2) + if ct.includeDC3 { + ct.addMeshGateways(dc3) + } - setupGlobals(dc1) - setupGlobals(dc2) - setupGlobals(dc3) + ct.setupGlobals(dc1) + ct.setupGlobals(dc2) + if ct.includeDC3 { + ct.setupGlobals(dc3) + } + + networks := []*topology.Network{ + {Name: "wan", Type: "wan"}, + {Name: dc1.Datacenter}, // "dc1" LAN + {Name: dc2.Datacenter}, // "dc2" LAN + } + if ct.includeDC3 { + networks = append(networks, &topology.Network{Name: dc3.Datacenter}) + } // Build final configuration ct.Cfg = &topology.Config{ - Images: utils.TargetImages(), - Networks: []*topology.Network{ - {Name: dc1.Datacenter}, // "dc1" LAN - {Name: dc2.Datacenter}, // "dc2" LAN - {Name: dc3.Datacenter}, // "dc3" LAN - {Name: "wan", Type: "wan"}, - }, - Clusters: []*topology.Cluster{ - dc1, - dc2, - dc3, - }, + Images: utils.TargetImages(), + Networks: networks, + Clusters: clusters, Peerings: peerings, } return &ct @@ -122,14 +156,14 @@ func (ct *commonTopo) Launch(t *testing.T) { } ct.Sprawl = sprawltest.Launch(t, ct.Cfg) - ct.Assert = newAsserter(ct.Sprawl) + ct.Assert = topoutil.NewAsserter(ct.Sprawl) ct.postLaunchChecks(t) } // tests that use Relaunch might want to call this again afterwards func (ct *commonTopo) postLaunchChecks(t *testing.T) { t.Logf("TESTING RELATIONSHIPS: \n%s", - renderRelationships(computeRelationships(ct.Sprawl.Topology())), + topology.RenderRelationships(ct.Sprawl.Topology().ComputeRelationships()), ) // check that exports line up as expected @@ -144,10 +178,12 @@ func (ct *commonTopo) postLaunchChecks(t *testing.T) { for _, e := range clu.InitialConfigEntries { if e.GetKind() == api.ExportedServices { asExport := e.(*api.ExportedServicesConfigEntry) - // do we care about the partition? for _, svc := range asExport.Services { for _, con := range svc.Consumers { - // do we care about con.Partition? + // if Peer is unset, this is an export to another partition in the same DC, so we don't need to check it + if con.Peer == "" { + continue + } // TODO: surely there is code to normalize this partition := asExport.Partition if partition == "" { @@ -185,6 +221,9 @@ func (ct *commonTopo) postLaunchChecks(t *testing.T) { // PeerName is how you'd address a remote dc+partition locally // as your peer name. func LocalPeerName(clu *topology.Cluster, partition string) string { + if partition == "" { + partition = "default" + } return fmt.Sprintf("peer-%s-%s", clu.Datacenter, partition) } @@ -229,7 +268,7 @@ func (ct *commonTopo) AddServiceNode(clu *topology.Cluster, svc serviceExt) *top nodeKind := topology.NodeKindClient // TODO: bug in deployer somewhere; it should guard against a KindDataplane node with // DisableServiceMesh services on it; dataplane is only for service-mesh - if !svc.DisableServiceMesh && clu.Datacenter == agentlessDC { + if !svc.DisableServiceMesh && clu.Datacenter == ct.agentlessDC { nodeKind = topology.NodeKindDataplane } @@ -308,54 +347,32 @@ func (ct *commonTopo) ClusterByDatacenter(t *testing.T, name string) *topology.C return nil } -// Since CE config entries do not contain the partition field, -// this func converts default partition to empty string. +// Deprecated: topoutil.ConfigEntryPartition func ConfigEntryPartition(p string) string { - if p == "default" { - return "" // make this CE friendly - } - return p + return topoutil.ConfigEntryPartition(p) } -// disableNode is a no-op if the node is already disabled. +// DisableNode is a no-op if the node is already disabled. func DisableNode(t *testing.T, cfg *topology.Config, clusterName string, nid topology.NodeID) *topology.Config { - nodes := cfg.Cluster(clusterName).Nodes - var found bool - for _, n := range nodes { - if n.ID() == nid { - found = true - if n.Disabled { - return cfg - } - t.Logf("disabling node %s in cluster %s", nid.String(), clusterName) - n.Disabled = true - break - } + changed, err := cfg.DisableNode(clusterName, nid) + require.NoError(t, err) + if changed { + t.Logf("disabling node %s in cluster %s", nid.String(), clusterName) } - require.True(t, found, "expected to find nodeID %q in cluster %q", nid.String(), clusterName) return cfg } -// enableNode is a no-op if the node is already enabled. +// EnableNode is a no-op if the node is already enabled. func EnableNode(t *testing.T, cfg *topology.Config, clusterName string, nid topology.NodeID) *topology.Config { - nodes := cfg.Cluster(clusterName).Nodes - var found bool - for _, n := range nodes { - if n.ID() == nid { - found = true - if !n.Disabled { - return cfg - } - t.Logf("enabling node %s in cluster %s", nid.String(), clusterName) - n.Disabled = false - break - } + changed, err := cfg.EnableNode(clusterName, nid) + require.NoError(t, err) + if changed { + t.Logf("enabling node %s in cluster %s", nid.String(), clusterName) } - require.True(t, found, "expected to find nodeID %q in cluster %q", nid.String(), clusterName) return cfg } -func setupGlobals(clu *topology.Cluster) { +func (ct *commonTopo) setupGlobals(clu *topology.Cluster) { for _, part := range clu.Partitions { clu.InitialConfigEntries = append(clu.InitialConfigEntries, &api.ProxyConfigEntry{ @@ -369,43 +386,71 @@ func setupGlobals(clu *topology.Cluster) { Mode: api.MeshGatewayModeLocal, }, }, - &api.MeshConfigEntry{ - Peering: &api.PeeringMeshConfig{ - PeerThroughMeshGateways: true, - }, - }, ) + if ct.peerThroughMGW { + clu.InitialConfigEntries = append(clu.InitialConfigEntries, + &api.MeshConfigEntry{ + Peering: &api.PeeringMeshConfig{ + PeerThroughMeshGateways: true, + }, + }, + ) + } } } // addMeshGateways adds a mesh gateway for every partition in the cluster. // Assumes that the LAN network name is equal to datacenter name. -func addMeshGateways(c *topology.Cluster) { +func (ct *commonTopo) addMeshGateways(c *topology.Cluster) { nodeKind := topology.NodeKindClient - if c.Datacenter == agentlessDC { + if c.Datacenter == ct.agentlessDC { nodeKind = topology.NodeKindDataplane } for _, p := range c.Partitions { - c.Nodes = topology.MergeSlices(c.Nodes, newTopologyMeshGatewaySet( + sid, nodes := newTopologyMeshGatewaySet( nodeKind, p.Name, fmt.Sprintf("%s-%s-mgw", c.Name, p.Name), 1, []string{c.Datacenter, "wan"}, nil, - )) + ) + c.Nodes = topology.MergeSlices(c.Nodes, nodes) + // for services exported in the same cluster between partitions, we need + // to export the mesh gateway (but not for peering) + // https://github.com/hashicorp/consul/pull/19052 + consumers := []api.ServiceConsumer{} + for _, cp := range c.Partitions { + if cp.Name == p.Name { + continue + } + consumers = append(consumers, api.ServiceConsumer{ + Partition: cp.Name, + }) + } + if len(consumers) > 0 { + ct.ExportService(c, p.Name, api.ExportedService{ + Name: sid.Name, + Namespace: sid.Namespace, + Consumers: consumers, + }) + } } } -func clusterWithJustServers(name string, numServers int) *topology.Cluster { +func (ct *commonTopo) clusterWithJustServers(name string, numServers int) *topology.Cluster { + nets := []string{name} + if !ct.peerThroughMGW { + nets = append(nets, "wan") + } return &topology.Cluster{ Enterprise: utils.IsEnterprise(), Name: name, Datacenter: name, - Nodes: newTopologyServerSet( + Nodes: topoutil.NewTopologyServerSet( name+"-server", numServers, - []string{name}, + nets, nil, ), } @@ -458,31 +503,13 @@ func injectTenancies(clu *topology.Cluster) { } } -func newTopologyServerSet( - namePrefix string, - num int, - networks []string, - mutateFn func(i int, node *topology.Node), -) []*topology.Node { - var out []*topology.Node - for i := 1; i <= num; i++ { - name := namePrefix + strconv.Itoa(i) - - node := &topology.Node{ - Kind: topology.NodeKindServer, - Name: name, - } - for _, net := range networks { - node.Addresses = append(node.Addresses, &topology.Address{Network: net}) - } - - if mutateFn != nil { - mutateFn(i, node) - } - - out = append(out, node) - } - return out +// Deprecated: topoutil.NewFortioServiceWithDefaults +func NewFortioServiceWithDefaults( + cluster string, + sid topology.ServiceID, + mut func(s *topology.Service), +) *topology.Service { + return topoutil.NewFortioServiceWithDefaults(cluster, sid, topology.NodeVersionV1, mut) } func newTopologyMeshGatewaySet( @@ -492,134 +519,8 @@ func newTopologyMeshGatewaySet( num int, networks []string, mutateFn func(i int, node *topology.Node), -) []*topology.Node { - var out []*topology.Node - for i := 1; i <= num; i++ { - name := namePrefix + strconv.Itoa(i) - - node := &topology.Node{ - Kind: nodeKind, - Partition: partition, - Name: name, - Services: []*topology.Service{{ - ID: topology.ServiceID{Name: "mesh-gateway"}, - Port: 8443, - EnvoyAdminPort: 19000, - IsMeshGateway: true, - }}, - } - for _, net := range networks { - node.Addresses = append(node.Addresses, &topology.Address{Network: net}) - } - - if mutateFn != nil { - mutateFn(i, node) - } - - out = append(out, node) - } - return out -} - -const HashicorpDockerProxy = "docker.mirror.hashicorp.services" - -func NewFortioServiceWithDefaults( - cluster string, - sid topology.ServiceID, - mut func(s *topology.Service), -) *topology.Service { - const ( - httpPort = 8080 - grpcPort = 8079 - adminPort = 19000 - ) - sid.Normalize() - - svc := &topology.Service{ - ID: sid, - Image: HashicorpDockerProxy + "/fortio/fortio", - Port: httpPort, - EnvoyAdminPort: adminPort, - CheckTCP: "127.0.0.1:" + strconv.Itoa(httpPort), - Env: []string{ - "FORTIO_NAME=" + cluster + "::" + sid.String(), - }, - Command: []string{ - "server", - "-http-port", strconv.Itoa(httpPort), - "-grpc-port", strconv.Itoa(grpcPort), - "-redirect-port", "-disabled", - }, - } - if mut != nil { - mut(svc) - } - return svc -} - -// computeRelationships will analyze a full topology and generate all of the -// downstream/upstream information for all of them. -func computeRelationships(topo *topology.Topology) []Relationship { - var out []Relationship - for _, cluster := range topo.Clusters { - for _, n := range cluster.Nodes { - for _, s := range n.Services { - for _, u := range s.Upstreams { - out = append(out, Relationship{ - Caller: s, - Upstream: u, - }) - } - } - } - } - return out -} - -// renderRelationships will take the output of ComputeRelationships and display -// it in tabular form. -func renderRelationships(ships []Relationship) string { - var buf bytes.Buffer - w := tabwriter.NewWriter(&buf, 0, 0, 3, ' ', tabwriter.Debug) - fmt.Fprintf(w, "DOWN\tnode\tservice\tport\tUP\tservice\t\n") - for _, r := range ships { - fmt.Fprintf(w, - "%s\t%s\t%s\t%d\t%s\t%s\t\n", - r.downCluster(), - r.Caller.Node.ID().String(), - r.Caller.ID.String(), - r.Upstream.LocalPort, - r.upCluster(), - r.Upstream.ID.String(), - ) - } - fmt.Fprintf(w, "\t\t\t\t\t\t\n") - - w.Flush() - return buf.String() -} - -type Relationship struct { - Caller *topology.Service - Upstream *topology.Upstream -} - -func (r Relationship) String() string { - return fmt.Sprintf( - "%s on %s in %s via :%d => %s in %s", - r.Caller.ID.String(), - r.Caller.Node.ID().String(), - r.downCluster(), - r.Upstream.LocalPort, - r.Upstream.ID.String(), - r.upCluster(), - ) -} - -func (r Relationship) downCluster() string { - return r.Caller.Node.Cluster -} - -func (r Relationship) upCluster() string { - return r.Upstream.Cluster +) (topology.ServiceID, []*topology.Node) { + nodes := topoutil.NewTopologyMeshGatewaySet(nodeKind, partition, namePrefix, num, networks, mutateFn) + sid := nodes[0].Services[0].ID + return sid, nodes } diff --git a/test-integ/peering_commontopo/asserter.go b/test-integ/topoutil/asserter.go similarity index 70% rename from test-integ/peering_commontopo/asserter.go rename to test-integ/topoutil/asserter.go index b5aa71ebae45..dd0500922c69 100644 --- a/test-integ/peering_commontopo/asserter.go +++ b/test-integ/topoutil/asserter.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: BUSL-1.1 -package peering +package topoutil import ( "fmt" @@ -12,18 +12,17 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - "github.com/hashicorp/consul/testing/deployer/topology" - "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil/retry" libassert "github.com/hashicorp/consul/test/integration/consul-container/libs/assert" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" + "github.com/hashicorp/consul/testing/deployer/topology" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -// asserter is a utility to help in reducing boilerplate in invoking test +// Asserter is a utility to help in reducing boilerplate in invoking test // assertions against consul-topology Sprawl components. // // The methods should largely take in *topology.Service instances in lieu of @@ -33,32 +32,33 @@ import ( // If it's up to the test (like picking an upstream) leave port as an argument // but still take the service and use that to grab the local ip from the // topology.Node. -type asserter struct { - sp sprawlLite +type Asserter struct { + sp SprawlLite } // *sprawl.Sprawl satisfies this. We don't need anything else. -type sprawlLite interface { +type SprawlLite interface { HTTPClientForCluster(clusterName string) (*http.Client, error) APIClientForNode(clusterName string, nid topology.NodeID, token string) (*api.Client, error) APIClientForCluster(clusterName string, token string) (*api.Client, error) + ResourceServiceClientForCluster(clusterName string) pbresource.ResourceServiceClient Topology() *topology.Topology } -// newAsserter creates a new assertion helper for the provided sprawl. -func newAsserter(sp sprawlLite) *asserter { - return &asserter{ +// NewAsserter creates a new assertion helper for the provided sprawl. +func NewAsserter(sp SprawlLite) *Asserter { + return &Asserter{ sp: sp, } } -func (a *asserter) mustGetHTTPClient(t *testing.T, cluster string) *http.Client { +func (a *Asserter) mustGetHTTPClient(t *testing.T, cluster string) *http.Client { client, err := a.httpClientFor(cluster) require.NoError(t, err) return client } -func (a *asserter) mustGetAPIClient(t *testing.T, cluster string) *api.Client { +func (a *Asserter) mustGetAPIClient(t *testing.T, cluster string) *api.Client { clu := a.sp.Topology().Clusters[cluster] cl, err := a.sp.APIClientForCluster(clu.Name, "") require.NoError(t, err) @@ -70,7 +70,7 @@ func (a *asserter) mustGetAPIClient(t *testing.T, cluster string) *api.Client { // // Use this in methods below to magically pick the right proxied http client // given the home of each node being checked. -func (a *asserter) httpClientFor(cluster string) (*http.Client, error) { +func (a *Asserter) httpClientFor(cluster string) (*http.Client, error) { client, err := a.sp.HTTPClientForCluster(cluster) if err != nil { return nil, err @@ -83,7 +83,7 @@ func (a *asserter) httpClientFor(cluster string) (*http.Client, error) { // Exposes libassert.UpstreamEndpointStatus for use against a Sprawl. // // NOTE: this doesn't take a port b/c you always want to use the envoy admin port. -func (a *asserter) UpstreamEndpointStatus( +func (a *Asserter) UpstreamEndpointStatus( t *testing.T, service *topology.Service, clusterName string, @@ -107,7 +107,7 @@ func (a *asserter) UpstreamEndpointStatus( // Exposes libassert.HTTPServiceEchoes for use against a Sprawl. // // NOTE: this takes a port b/c you may want to reach this via your choice of upstream. -func (a *asserter) HTTPServiceEchoes( +func (a *Asserter) HTTPServiceEchoes( t *testing.T, service *topology.Service, port int, @@ -131,7 +131,7 @@ func (a *asserter) HTTPServiceEchoes( // Exposes libassert.HTTPServiceEchoes for use against a Sprawl. // // NOTE: this takes a port b/c you may want to reach this via your choice of upstream. -func (a *asserter) HTTPServiceEchoesResHeader( +func (a *Asserter) HTTPServiceEchoesResHeader( t *testing.T, service *topology.Service, port int, @@ -149,7 +149,7 @@ func (a *asserter) HTTPServiceEchoesResHeader( libassert.HTTPServiceEchoesResHeaderWithClient(t, client, addr, path, expectedResHeader) } -func (a *asserter) HTTPStatus( +func (a *Asserter) HTTPStatus( t *testing.T, service *topology.Service, port int, @@ -179,7 +179,7 @@ func (a *asserter) HTTPStatus( } // asserts that the service sid in cluster and exported by peer localPeerName is passing health checks, -func (a *asserter) HealthyWithPeer(t *testing.T, cluster string, sid topology.ServiceID, peerName string) { +func (a *Asserter) HealthyWithPeer(t *testing.T, cluster string, sid topology.ServiceID, peerName string) { t.Helper() cl := a.mustGetAPIClient(t, cluster) retry.RunWith(&retry.Timer{Timeout: time.Minute * 1, Wait: time.Millisecond * 500}, t, func(r *retry.R) { @@ -198,86 +198,105 @@ func (a *asserter) HealthyWithPeer(t *testing.T, cluster string, sid topology.Se }) } -func (a *asserter) UpstreamEndpointHealthy(t *testing.T, svc *topology.Service, upstream *topology.Upstream) { - t.Helper() - node := svc.Node - ip := node.LocalAddress() - port := svc.EnvoyAdminPort - addr := fmt.Sprintf("%s:%d", ip, port) - - client := a.mustGetHTTPClient(t, node.Cluster) - libassert.AssertUpstreamEndpointStatusWithClient(t, - client, - addr, - // TODO: what is default? namespace? partition? - fmt.Sprintf("%s.default.%s.external", upstream.ID.Name, upstream.Peer), - "HEALTHY", - 1, - ) +type testingT interface { + require.TestingT + Helper() } // does a fortio /fetch2 to the given fortio service, targetting the given upstream. Returns // the body, and response with response.Body already Closed. // // We treat 400, 503, and 504s as retryable errors -func (a *asserter) fortioFetch2Upstream(t *testing.T, fortioSvc *topology.Service, upstream *topology.Upstream, path string) (body []byte, res *http.Response) { +func (a *Asserter) fortioFetch2Upstream( + t testingT, + client *http.Client, + addr string, + upstream *topology.Upstream, + path string, +) (body []byte, res *http.Response) { t.Helper() - // TODO: fortioSvc.ID.Normalize()? or should that be up to the caller? - - node := fortioSvc.Node - client := a.mustGetHTTPClient(t, node.Cluster) - urlbase := fmt.Sprintf("%s:%d", node.LocalAddress(), fortioSvc.Port) + var actualURL string + if upstream.Implied { + actualURL = fmt.Sprintf("http://%s--%s--%s.virtual.consul:%d/%s", + upstream.ID.Name, + upstream.ID.Namespace, + upstream.ID.Partition, + upstream.VirtualPort, + path, + ) + } else { + actualURL = fmt.Sprintf("http://localhost:%d/%s", upstream.LocalPort, path) + } - url := fmt.Sprintf("http://%s/fortio/fetch2?url=%s", urlbase, - url.QueryEscape(fmt.Sprintf("http://localhost:%d/%s", upstream.LocalPort, path)), + url := fmt.Sprintf("http://%s/fortio/fetch2?url=%s", addr, + url.QueryEscape(actualURL), ) req, err := http.NewRequest(http.MethodPost, url, nil) require.NoError(t, err) - retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - res, err = client.Do(req) - require.NoError(r, err) - defer res.Body.Close() - // not sure when these happen, suspect it's when the mesh gateway in the peer is not yet ready - require.NotEqual(r, http.StatusServiceUnavailable, res.StatusCode) - require.NotEqual(r, http.StatusGatewayTimeout, res.StatusCode) - // not sure when this happens, suspect it's when envoy hasn't configured the local upstream yet - require.NotEqual(r, http.StatusBadRequest, res.StatusCode) - body, err = io.ReadAll(res.Body) - require.NoError(r, err) - }) + + res, err = client.Do(req) + require.NoError(t, err) + defer res.Body.Close() + + // not sure when these happen, suspect it's when the mesh gateway in the peer is not yet ready + require.NotEqual(t, http.StatusServiceUnavailable, res.StatusCode) + require.NotEqual(t, http.StatusGatewayTimeout, res.StatusCode) + // not sure when this happens, suspect it's when envoy hasn't configured the local upstream yet + require.NotEqual(t, http.StatusBadRequest, res.StatusCode) + body, err = io.ReadAll(res.Body) + require.NoError(t, err) return body, res } // uses the /fortio/fetch2 endpoint to do a header echo check against an // upstream fortio -func (a *asserter) FortioFetch2HeaderEcho(t *testing.T, fortioSvc *topology.Service, upstream *topology.Upstream) { +func (a *Asserter) FortioFetch2HeaderEcho(t *testing.T, fortioSvc *topology.Service, upstream *topology.Upstream) { const kPassphrase = "x-passphrase" const passphrase = "hello" path := (fmt.Sprintf("/?header=%s:%s", kPassphrase, passphrase)) + var ( + node = fortioSvc.Node + addr = fmt.Sprintf("%s:%d", node.LocalAddress(), fortioSvc.PortOrDefault("http")) + client = a.mustGetHTTPClient(t, node.Cluster) + ) + retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - _, res := a.fortioFetch2Upstream(t, fortioSvc, upstream, path) - require.Equal(t, http.StatusOK, res.StatusCode) + _, res := a.fortioFetch2Upstream(r, client, addr, upstream, path) + require.Equal(r, http.StatusOK, res.StatusCode) v := res.Header.Get(kPassphrase) - require.Equal(t, passphrase, v) + require.Equal(r, passphrase, v) }) } // similar to libassert.AssertFortioName, // uses the /fortio/fetch2 endpoint to hit the debug endpoint on the upstream, // and assert that the FORTIO_NAME == name -func (a *asserter) FortioFetch2FortioName(t *testing.T, fortioSvc *topology.Service, upstream *topology.Upstream, clusterName string, sid topology.ServiceID) { +func (a *Asserter) FortioFetch2FortioName( + t *testing.T, + fortioSvc *topology.Service, + upstream *topology.Upstream, + clusterName string, + sid topology.ServiceID, +) { t.Helper() + var ( + node = fortioSvc.Node + addr = fmt.Sprintf("%s:%d", node.LocalAddress(), fortioSvc.PortOrDefault("http")) + client = a.mustGetHTTPClient(t, node.Cluster) + ) + var fortioNameRE = regexp.MustCompile(("\nFORTIO_NAME=(.+)\n")) path := "/debug?env=dump" retry.RunWith(&retry.Timer{Timeout: 60 * time.Second, Wait: time.Millisecond * 500}, t, func(r *retry.R) { - body, res := a.fortioFetch2Upstream(t, fortioSvc, upstream, path) - require.Equal(t, http.StatusOK, res.StatusCode) + body, res := a.fortioFetch2Upstream(r, client, addr, upstream, path) + + require.Equal(r, http.StatusOK, res.StatusCode) // TODO: not sure we should retry these? m := fortioNameRE.FindStringSubmatch(string(body)) @@ -289,7 +308,7 @@ func (a *asserter) FortioFetch2FortioName(t *testing.T, fortioSvc *topology.Serv // CatalogServiceExists is the same as libassert.CatalogServiceExists, except that it uses // a proxied API client -func (a *asserter) CatalogServiceExists(t *testing.T, cluster string, svc string, opts *api.QueryOptions) { +func (a *Asserter) CatalogServiceExists(t *testing.T, cluster string, svc string, opts *api.QueryOptions) { t.Helper() cl := a.mustGetAPIClient(t, cluster) libassert.CatalogServiceExists(t, cl, svc, opts) diff --git a/test-integ/topoutil/fixtures.go b/test-integ/topoutil/fixtures.go new file mode 100644 index 000000000000..a0c72e246a93 --- /dev/null +++ b/test-integ/topoutil/fixtures.go @@ -0,0 +1,137 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package topoutil + +import ( + "strconv" + + "github.com/hashicorp/consul/testing/deployer/topology" +) + +const HashicorpDockerProxy = "docker.mirror.hashicorp.services" + +func NewFortioServiceWithDefaults( + cluster string, + sid topology.ServiceID, + nodeVersion topology.NodeVersion, + mut func(s *topology.Service), +) *topology.Service { + const ( + httpPort = 8080 + grpcPort = 8079 + adminPort = 19000 + ) + sid.Normalize() + + svc := &topology.Service{ + ID: sid, + Image: HashicorpDockerProxy + "/fortio/fortio", + EnvoyAdminPort: adminPort, + CheckTCP: "127.0.0.1:" + strconv.Itoa(httpPort), + Env: []string{ + "FORTIO_NAME=" + cluster + "::" + sid.String(), + }, + Command: []string{ + "server", + "-http-port", strconv.Itoa(httpPort), + "-grpc-port", strconv.Itoa(grpcPort), + "-redirect-port", "-disabled", + }, + } + + if nodeVersion == topology.NodeVersionV2 { + svc.Ports = map[string]*topology.Port{ + // TODO(rb/v2): once L7 works in v2 switch these back + "http": {Number: httpPort, Protocol: "tcp"}, + "http-alt": {Number: httpPort, Protocol: "tcp"}, + "grpc": {Number: grpcPort, Protocol: "tcp"}, + // "http": {Number: httpPort, Protocol: "http"}, + // "http-alt": {Number: httpPort, Protocol: "http"}, + // "grpc": {Number: grpcPort, Protocol: "grpc"}, + } + } else { + svc.Port = httpPort + } + + if mut != nil { + mut(svc) + } + return svc +} + +func NewTopologyServerSet( + namePrefix string, + num int, + networks []string, + mutateFn func(i int, node *topology.Node), +) []*topology.Node { + var out []*topology.Node + for i := 1; i <= num; i++ { + name := namePrefix + strconv.Itoa(i) + + node := &topology.Node{ + Kind: topology.NodeKindServer, + Name: name, + } + for _, net := range networks { + node.Addresses = append(node.Addresses, &topology.Address{Network: net}) + } + + if mutateFn != nil { + mutateFn(i, node) + } + + out = append(out, node) + } + return out +} + +func NewTopologyMeshGatewaySet( + nodeKind topology.NodeKind, + partition string, + namePrefix string, + num int, + networks []string, + mutateFn func(i int, node *topology.Node), +) []*topology.Node { + var out []*topology.Node + sid := topology.ServiceID{ + Name: "mesh-gateway", + Partition: ConfigEntryPartition(partition), + } + for i := 1; i <= num; i++ { + name := namePrefix + strconv.Itoa(i) + + node := &topology.Node{ + Kind: nodeKind, + Partition: partition, + Name: name, + Services: []*topology.Service{{ + ID: sid, + Port: 8443, + EnvoyAdminPort: 19000, + IsMeshGateway: true, + }}, + } + for _, net := range networks { + node.Addresses = append(node.Addresses, &topology.Address{Network: net}) + } + + if mutateFn != nil { + mutateFn(i, node) + } + + out = append(out, node) + } + return out +} + +// Since CE config entries do not contain the partition field, +// this func converts default partition to empty string. +func ConfigEntryPartition(p string) string { + if p == "default" { + return "" // make this CE friendly + } + return p +} diff --git a/test-integ/topoutil/images.go b/test-integ/topoutil/images.go new file mode 100644 index 000000000000..855ba8c2a9a3 --- /dev/null +++ b/test-integ/topoutil/images.go @@ -0,0 +1,36 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package topoutil + +import ( + "os" + + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" + "github.com/hashicorp/consul/testing/deployer/topology" +) + +func TargetImages() topology.Images { + // Start with no preferences. + var images topology.Images + if !runningInCI() { + // Until 1.17 GAs, we want the pre-release versions for these tests, + // run outside of CI for convenience. + images = topology.Images{ + ConsulCE: HashicorpDockerProxy + "/hashicorppreview/consul:1.17-dev", + ConsulEnterprise: HashicorpDockerProxy + "/hashicorppreview/consul-enterprise:1.17-dev", + Dataplane: HashicorpDockerProxy + "/hashicorppreview/consul-dataplane:1.3-dev", + } + } + + // We want the image overridden by the local build produced by + // 'make test-compat-integ-setup' or 'make dev-docker'. + testImages := utils.TargetImages() + images = images.OverrideWith(testImages) + + return images +} + +func runningInCI() bool { + return os.Getenv("GITHUB_ACTIONS") != "" || os.Getenv("CI") != "" +} diff --git a/test/CA-GENERATION.md b/test/CA-GENERATION.md index 0c2c8b4dbe4f..2e278f2b0a55 100644 --- a/test/CA-GENERATION.md +++ b/test/CA-GENERATION.md @@ -22,5 +22,6 @@ if tests like `TestNewDialer_WithALPNWrapper` (or any other test using certifica ``` bash cd test/hostname/ -rm -rf *.pem *.crt *.key && ./generate.sh +# Avoid deleting CertAuth.crt and privkey.pem since they're referenced in myca.conf +rm -rf "[Bonnie|Betty|Bob|Alice].crt" *.key && ./generate.sh ``` \ No newline at end of file diff --git a/test/client_certs/client.crt b/test/client_certs/client.crt index 263da23b07d0..e9b136f03ecb 100644 --- a/test/client_certs/client.crt +++ b/test/client_certs/client.crt @@ -1,16 +1,17 @@ -----BEGIN CERTIFICATE----- -MIICnDCCAkKgAwIBAgIQBEmjZ8EghLtV+7EC+jUSlzAKBggqhkjOPQQDAjCBuTEL -MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv -MRowGAYDVQQJExExMDEgU2Vjb25kIFN0cmVldDEOMAwGA1UEERMFOTQxMDUxFzAV -BgNVBAoTDkhhc2hpQ29ycCBJbmMuMUAwPgYDVQQDEzdDb25zdWwgQWdlbnQgQ0Eg -MzI0NTYxNDUyNjQ2NDU0MDY2Mjk1MzU5NzAzNzcxNTM4MDY2MTQ1MB4XDTIyMTEw -MTE1MTczNVoXDTIzMTEwMTE1MTczNVowHDEaMBgGA1UEAxMRY2xpZW50LmRjMS5j -b25zdWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQJqvEGn2AswWZQ1mr0tHlt -ftn9J9lyCSdWrOADhB3+GMgz4H44CKYsYVrVtu5KMryXd2POHB/iU4xg8lm3M4GA -o4HHMIHEMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYB -BQUHAwEwDAYDVR0TAQH/BAIwADApBgNVHQ4EIgQg/GP6DmucHJbreVDyMqdZykvt -AvXQ+OagDurF1Kbic04wKwYDVR0jBCQwIoAg5ONc3k0++QDOnzWJI4N38lvRq5WS -az/dq8lQJyva894wLQYDVR0RBCYwJIIRY2xpZW50LmRjMS5jb25zdWyCCWxvY2Fs -aG9zdIcEfwAAATAKBggqhkjOPQQDAgNIADBFAiA6yknUjHv/sqbbSp0mEbW0dA5j -klHQMILw0QJqCOk/iQIhANeMu0qp9efaHAvTNIbjlUwn+EbKUIVS4tCw8ImuAMA8 +MIICnTCCAkOgAwIBAgIRAO78TJMhBu87zWa1WjcG5rkwCgYIKoZIzj0EAwIwgbkx +CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj +bzEaMBgGA1UECRMRMTAxIFNlY29uZCBTdHJlZXQxDjAMBgNVBBETBTk0MTA1MRcw +FQYDVQQKEw5IYXNoaUNvcnAgSW5jLjFAMD4GA1UEAxM3Q29uc3VsIEFnZW50IENB +IDIwNjQxNTYyNDA1MDIyOTg4MjQzNTI2NTMwNzkwODU3NzAyMzg4OTAeFw0yMzEx +MDIxNDA2MDhaFw0yNDExMDExNDA2MDhaMBwxGjAYBgNVBAMTEWNsaWVudC5kYzEu +Y29uc3VsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcSaUbB8GT/WlJjIvvbjE +dgs7hEJqUrU5POXv8N9tNAe/FRbb1yBFU2dBrHgBlJp+sp0gp3cRUCzQMkLO5acw +lqOBxzCBxDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsG +AQUFBwMBMAwGA1UdEwEB/wQCMAAwKQYDVR0OBCIEIGV49e7k/a39oKuJCrdyF0Hs +cgoZx+I2WwMGaT5soLG1MCsGA1UdIwQkMCKAIJqCAzNWlJBk68ytAJtnqLtvw2Vl +lImVNZXwhWrSbD5wMC0GA1UdEQQmMCSCEWNsaWVudC5kYzEuY29uc3Vsgglsb2Nh +bGhvc3SHBH8AAAEwCgYIKoZIzj0EAwIDSAAwRQIhAPnAeouhL4lCbOuYj6REbJ2q +WZDLv5j7AY5uXoLOtMgLAiALUk1/M2oUO1y61qTMLdCGQh3g6gKpSEB1vo/el1hQ +VA== -----END CERTIFICATE----- diff --git a/test/client_certs/client.key b/test/client_certs/client.key index 17a6630af418..ef5f3a7e04fc 100644 --- a/test/client_certs/client.key +++ b/test/client_certs/client.key @@ -1,5 +1,5 @@ -----BEGIN EC PRIVATE KEY----- -MHcCAQEEIOEmrph3YiKjf2pUN/cy0G8LNvMVYSXM4fl7w9ylpaXLoAoGCCqGSM49 -AwEHoUQDQgAECarxBp9gLMFmUNZq9LR5bX7Z/SfZcgknVqzgA4Qd/hjIM+B+OAim -LGFa1bbuSjK8l3djzhwf4lOMYPJZtzOBgA== +MHcCAQEEILsRH87p2w58u2Re7XGAmPuI1grBy7ZMsxWDP7tJ/pL0oAoGCCqGSM49 +AwEHoUQDQgAEcSaUbB8GT/WlJjIvvbjEdgs7hEJqUrU5POXv8N9tNAe/FRbb1yBF +U2dBrHgBlJp+sp0gp3cRUCzQMkLO5acwlg== -----END EC PRIVATE KEY----- diff --git a/test/client_certs/consul-agent-ca-key.pem b/test/client_certs/consul-agent-ca-key.pem index 4493d2f01961..f3b6cb6d57ac 100644 --- a/test/client_certs/consul-agent-ca-key.pem +++ b/test/client_certs/consul-agent-ca-key.pem @@ -1,5 +1,5 @@ -----BEGIN EC PRIVATE KEY----- -MHcCAQEEILDGZMNL2mZRmk9LLUm+Ocp2PK31o0BtoTUZ6jqTz8lioAoGCCqGSM49 -AwEHoUQDQgAE4wstVIecTLB40vS0ujhIrF58KRdqYijsMRcZL9ZEcmPwVuA1RZ4P -VfMhqHDRirX0KwuRhunlFsCy0wQpy3XqBA== +MHcCAQEEICDZ+CIUIyHeCulc0Av0afGc6iUrXp6LI+RMCtzXq2f/oAoGCCqGSM49 +AwEHoUQDQgAEdegVURrrCMAdJqm065wYxHwr1HgocnVd+NPABufHiTJPPY4EIucf +WfpCvVBd3a5quRkZRobnQYK4BHPMFPm2Qg== -----END EC PRIVATE KEY----- diff --git a/test/client_certs/consul-agent-ca.pem b/test/client_certs/consul-agent-ca.pem index a62c8916e2d5..f57e1cb34f00 100644 --- a/test/client_certs/consul-agent-ca.pem +++ b/test/client_certs/consul-agent-ca.pem @@ -1,18 +1,18 @@ -----BEGIN CERTIFICATE----- -MIIC7jCCApSgAwIBAgIRAPQsQxVaOlwVK7QsleZhCuEwCgYIKoZIzj0EAwIwgbkx +MIIC7TCCApSgAwIBAgIRAJtKNACj8KAiBWSSqeYB15EwCgYIKoZIzj0EAwIwgbkx CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj bzEaMBgGA1UECRMRMTAxIFNlY29uZCBTdHJlZXQxDjAMBgNVBBETBTk0MTA1MRcw FQYDVQQKEw5IYXNoaUNvcnAgSW5jLjFAMD4GA1UEAxM3Q29uc3VsIEFnZW50IENB -IDMyNDU2MTQ1MjY0NjQ1NDA2NjI5NTM1OTcwMzc3MTUzODA2NjE0NTAeFw0yMjEx -MDExNTE3MzVaFw0yNzEwMzExNTE3MzVaMIG5MQswCQYDVQQGEwJVUzELMAkGA1UE +IDIwNjQxNTYyNDA1MDIyOTg4MjQzNTI2NTMwNzkwODU3NzAyMzg4OTAeFw0yMzEx +MDIxNDA2MDhaFw0yODEwMzExNDA2MDhaMIG5MQswCQYDVQQGEwJVUzELMAkGA1UE CBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGjAYBgNVBAkTETEwMSBTZWNv bmQgU3RyZWV0MQ4wDAYDVQQREwU5NDEwNTEXMBUGA1UEChMOSGFzaGlDb3JwIElu -Yy4xQDA+BgNVBAMTN0NvbnN1bCBBZ2VudCBDQSAzMjQ1NjE0NTI2NDY0NTQwNjYy -OTUzNTk3MDM3NzE1MzgwNjYxNDUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATj -Cy1Uh5xMsHjS9LS6OEisXnwpF2piKOwxFxkv1kRyY/BW4DVFng9V8yGocNGKtfQr -C5GG6eUWwLLTBCnLdeoEo3sweTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zApBgNVHQ4EIgQg5ONc3k0++QDOnzWJI4N38lvRq5WSaz/dq8lQJyva894w -KwYDVR0jBCQwIoAg5ONc3k0++QDOnzWJI4N38lvRq5WSaz/dq8lQJyva894wCgYI -KoZIzj0EAwIDSAAwRQIhAKU8aWxhlJ5kiG/cqHkmfFZjY9MoweTEeSeq8ROUVYlK -AiB2nWWrkj7+KzNO4OIwNmCe8nY+JcpIMaKCK4QwhWg9uA== +Yy4xQDA+BgNVBAMTN0NvbnN1bCBBZ2VudCBDQSAyMDY0MTU2MjQwNTAyMjk4ODI0 +MzUyNjUzMDc5MDg1NzcwMjM4ODkwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR1 +6BVRGusIwB0mqbTrnBjEfCvUeChydV3408AG58eJMk89jgQi5x9Z+kK9UF3drmq5 +GRlGhudBgrgEc8wU+bZCo3sweTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zApBgNVHQ4EIgQgmoIDM1aUkGTrzK0Am2eou2/DZWWUiZU1lfCFatJsPnAw +KwYDVR0jBCQwIoAgmoIDM1aUkGTrzK0Am2eou2/DZWWUiZU1lfCFatJsPnAwCgYI +KoZIzj0EAwIDRwAwRAIgcoZwCzJGdL7LFL7Bbp+26OfNvnyhfchSDdN6YEukIVIC +IAd+GbxNZbSqTrIackV1/VkM0y1ZJ8si9IiecRNOKOMi -----END CERTIFICATE----- diff --git a/test/client_certs/dc1-client-consul-0-key.pem b/test/client_certs/dc1-client-consul-0-key.pem index 17a6630af418..ef5f3a7e04fc 100644 --- a/test/client_certs/dc1-client-consul-0-key.pem +++ b/test/client_certs/dc1-client-consul-0-key.pem @@ -1,5 +1,5 @@ -----BEGIN EC PRIVATE KEY----- -MHcCAQEEIOEmrph3YiKjf2pUN/cy0G8LNvMVYSXM4fl7w9ylpaXLoAoGCCqGSM49 -AwEHoUQDQgAECarxBp9gLMFmUNZq9LR5bX7Z/SfZcgknVqzgA4Qd/hjIM+B+OAim -LGFa1bbuSjK8l3djzhwf4lOMYPJZtzOBgA== +MHcCAQEEILsRH87p2w58u2Re7XGAmPuI1grBy7ZMsxWDP7tJ/pL0oAoGCCqGSM49 +AwEHoUQDQgAEcSaUbB8GT/WlJjIvvbjEdgs7hEJqUrU5POXv8N9tNAe/FRbb1yBF +U2dBrHgBlJp+sp0gp3cRUCzQMkLO5acwlg== -----END EC PRIVATE KEY----- diff --git a/test/client_certs/dc1-client-consul-0.pem b/test/client_certs/dc1-client-consul-0.pem index 263da23b07d0..e9b136f03ecb 100644 --- a/test/client_certs/dc1-client-consul-0.pem +++ b/test/client_certs/dc1-client-consul-0.pem @@ -1,16 +1,17 @@ -----BEGIN CERTIFICATE----- -MIICnDCCAkKgAwIBAgIQBEmjZ8EghLtV+7EC+jUSlzAKBggqhkjOPQQDAjCBuTEL -MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv -MRowGAYDVQQJExExMDEgU2Vjb25kIFN0cmVldDEOMAwGA1UEERMFOTQxMDUxFzAV -BgNVBAoTDkhhc2hpQ29ycCBJbmMuMUAwPgYDVQQDEzdDb25zdWwgQWdlbnQgQ0Eg -MzI0NTYxNDUyNjQ2NDU0MDY2Mjk1MzU5NzAzNzcxNTM4MDY2MTQ1MB4XDTIyMTEw -MTE1MTczNVoXDTIzMTEwMTE1MTczNVowHDEaMBgGA1UEAxMRY2xpZW50LmRjMS5j -b25zdWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQJqvEGn2AswWZQ1mr0tHlt -ftn9J9lyCSdWrOADhB3+GMgz4H44CKYsYVrVtu5KMryXd2POHB/iU4xg8lm3M4GA -o4HHMIHEMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYB -BQUHAwEwDAYDVR0TAQH/BAIwADApBgNVHQ4EIgQg/GP6DmucHJbreVDyMqdZykvt -AvXQ+OagDurF1Kbic04wKwYDVR0jBCQwIoAg5ONc3k0++QDOnzWJI4N38lvRq5WS -az/dq8lQJyva894wLQYDVR0RBCYwJIIRY2xpZW50LmRjMS5jb25zdWyCCWxvY2Fs -aG9zdIcEfwAAATAKBggqhkjOPQQDAgNIADBFAiA6yknUjHv/sqbbSp0mEbW0dA5j -klHQMILw0QJqCOk/iQIhANeMu0qp9efaHAvTNIbjlUwn+EbKUIVS4tCw8ImuAMA8 +MIICnTCCAkOgAwIBAgIRAO78TJMhBu87zWa1WjcG5rkwCgYIKoZIzj0EAwIwgbkx +CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj +bzEaMBgGA1UECRMRMTAxIFNlY29uZCBTdHJlZXQxDjAMBgNVBBETBTk0MTA1MRcw +FQYDVQQKEw5IYXNoaUNvcnAgSW5jLjFAMD4GA1UEAxM3Q29uc3VsIEFnZW50IENB +IDIwNjQxNTYyNDA1MDIyOTg4MjQzNTI2NTMwNzkwODU3NzAyMzg4OTAeFw0yMzEx +MDIxNDA2MDhaFw0yNDExMDExNDA2MDhaMBwxGjAYBgNVBAMTEWNsaWVudC5kYzEu +Y29uc3VsMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcSaUbB8GT/WlJjIvvbjE +dgs7hEJqUrU5POXv8N9tNAe/FRbb1yBFU2dBrHgBlJp+sp0gp3cRUCzQMkLO5acw +lqOBxzCBxDAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsG +AQUFBwMBMAwGA1UdEwEB/wQCMAAwKQYDVR0OBCIEIGV49e7k/a39oKuJCrdyF0Hs +cgoZx+I2WwMGaT5soLG1MCsGA1UdIwQkMCKAIJqCAzNWlJBk68ytAJtnqLtvw2Vl +lImVNZXwhWrSbD5wMC0GA1UdEQQmMCSCEWNsaWVudC5kYzEuY29uc3Vsgglsb2Nh +bGhvc3SHBH8AAAEwCgYIKoZIzj0EAwIDSAAwRQIhAPnAeouhL4lCbOuYj6REbJ2q +WZDLv5j7AY5uXoLOtMgLAiALUk1/M2oUO1y61qTMLdCGQh3g6gKpSEB1vo/el1hQ +VA== -----END CERTIFICATE----- diff --git a/test/client_certs/dc1-server-consul-0-key.pem b/test/client_certs/dc1-server-consul-0-key.pem index 9ef60bc14ebf..9e79d6a32b68 100644 --- a/test/client_certs/dc1-server-consul-0-key.pem +++ b/test/client_certs/dc1-server-consul-0-key.pem @@ -1,5 +1,5 @@ -----BEGIN EC PRIVATE KEY----- -MHcCAQEEIM+Rps/EV1QvlRwMo5IT9HMqWVe1LR5vfeernws0pwo8oAoGCCqGSM49 -AwEHoUQDQgAEwt5yBcpkGKSJ+LgcS0EuqdVt2NqXYSGMFU/RTqwjeTxNeGBEmBJD -3Rrnm0kj3+y25YL/ZhssI6WM4Az4JP5D8A== +MHcCAQEEIDBtgIlMLp68GuAx3GzgvqA6L4pzF7ra4U8KBAeAjYwroAoGCCqGSM49 +AwEHoUQDQgAE//3g7OUk49Wucef353sgAK2QAZJY5iiwYRHrKy8eGaEkBxJBFv0Z +QfXdtsFtJ3XuMk7OfDPEZ1g1VUYIRVPCbw== -----END EC PRIVATE KEY----- diff --git a/test/client_certs/dc1-server-consul-0.pem b/test/client_certs/dc1-server-consul-0.pem index cd8a64a1b0b4..a99eec5024d4 100644 --- a/test/client_certs/dc1-server-consul-0.pem +++ b/test/client_certs/dc1-server-consul-0.pem @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE----- -MIICxTCCAmqgAwIBAgIQQEFFmUhO6yA+4ScqpYgqoTAKBggqhkjOPQQDAjCBuTEL +MIICwzCCAmqgAwIBAgIQJeudmzJEAViQ9sIJfwC8RjAKBggqhkjOPQQDAjCBuTEL MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv MRowGAYDVQQJExExMDEgU2Vjb25kIFN0cmVldDEOMAwGA1UEERMFOTQxMDUxFzAV BgNVBAoTDkhhc2hpQ29ycCBJbmMuMUAwPgYDVQQDEzdDb25zdWwgQWdlbnQgQ0Eg -MzI0NTYxNDUyNjQ2NDU0MDY2Mjk1MzU5NzAzNzcxNTM4MDY2MTQ1MB4XDTIyMTEw -MTE1MTczNVoXDTIzMTEwMTE1MTczNVowHDEaMBgGA1UEAxMRc2VydmVyLmRjMS5j -b25zdWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATC3nIFymQYpIn4uBxLQS6p -1W3Y2pdhIYwVT9FOrCN5PE14YESYEkPdGuebSSPf7Lblgv9mGywjpYzgDPgk/kPw +MjA2NDE1NjI0MDUwMjI5ODgyNDM1MjY1MzA3OTA4NTc3MDIzODg5MB4XDTIzMTEw +MjE0MDYwOFoXDTI0MTEwMTE0MDYwOFowHDEaMBgGA1UEAxMRc2VydmVyLmRjMS5j +b25zdWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT//eDs5STj1a5x5/fneyAA +rZABkljmKLBhEesrLx4ZoSQHEkEW/RlB9d22wW0nde4yTs58M8RnWDVVRghFU8Jv o4HvMIHsMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB -BQUHAwIwDAYDVR0TAQH/BAIwADApBgNVHQ4EIgQgbvG1NZYTXB5wRZNGjgs+hgfT -1j+klGellDDkmXIZRpMwKwYDVR0jBCQwIoAg5ONc3k0++QDOnzWJI4N38lvRq5WS -az/dq8lQJyva894wVQYDVR0RBE4wTIILY29uc3VsLnRlc3SCGXNlcnZlcjAuc2Vy +BQUHAwIwDAYDVR0TAQH/BAIwADApBgNVHQ4EIgQgakV8pQCroFdBBW0TyFgVDbHB +ZFlLvu9sXfk6+xBtqY8wKwYDVR0jBCQwIoAgmoIDM1aUkGTrzK0Am2eou2/DZWWU +iZU1lfCFatJsPnAwVQYDVR0RBE4wTIILY29uc3VsLnRlc3SCGXNlcnZlcjAuc2Vy dmVyLmRjMS5jb25zdWyCEXNlcnZlci5kYzEuY29uc3Vsgglsb2NhbGhvc3SHBH8A -AAEwCgYIKoZIzj0EAwIDSQAwRgIhAIKx/BNuRx1STi9mupvpCFsl6vvTo6eKyvXk -YlMvo3X+AiEA6YTlNvH5+cWaJQORpX+ZI1Eogkl1h0oWNL4+D0lofIo= +AAEwCgYIKoZIzj0EAwIDRwAwRAIgB5HA/sAnp5EWLpo+PjM1SAoU6uiE5trKTBPE +UB5+NOoCICuz1zsVEuCTRo7dbFK5d5+G2gM7dwOU0E5nGFqCW46I -----END CERTIFICATE----- diff --git a/test/client_certs/path/rootca.crt b/test/client_certs/path/rootca.crt index a62c8916e2d5..f57e1cb34f00 100644 --- a/test/client_certs/path/rootca.crt +++ b/test/client_certs/path/rootca.crt @@ -1,18 +1,18 @@ -----BEGIN CERTIFICATE----- -MIIC7jCCApSgAwIBAgIRAPQsQxVaOlwVK7QsleZhCuEwCgYIKoZIzj0EAwIwgbkx +MIIC7TCCApSgAwIBAgIRAJtKNACj8KAiBWSSqeYB15EwCgYIKoZIzj0EAwIwgbkx CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj bzEaMBgGA1UECRMRMTAxIFNlY29uZCBTdHJlZXQxDjAMBgNVBBETBTk0MTA1MRcw FQYDVQQKEw5IYXNoaUNvcnAgSW5jLjFAMD4GA1UEAxM3Q29uc3VsIEFnZW50IENB -IDMyNDU2MTQ1MjY0NjQ1NDA2NjI5NTM1OTcwMzc3MTUzODA2NjE0NTAeFw0yMjEx -MDExNTE3MzVaFw0yNzEwMzExNTE3MzVaMIG5MQswCQYDVQQGEwJVUzELMAkGA1UE +IDIwNjQxNTYyNDA1MDIyOTg4MjQzNTI2NTMwNzkwODU3NzAyMzg4OTAeFw0yMzEx +MDIxNDA2MDhaFw0yODEwMzExNDA2MDhaMIG5MQswCQYDVQQGEwJVUzELMAkGA1UE CBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGjAYBgNVBAkTETEwMSBTZWNv bmQgU3RyZWV0MQ4wDAYDVQQREwU5NDEwNTEXMBUGA1UEChMOSGFzaGlDb3JwIElu -Yy4xQDA+BgNVBAMTN0NvbnN1bCBBZ2VudCBDQSAzMjQ1NjE0NTI2NDY0NTQwNjYy -OTUzNTk3MDM3NzE1MzgwNjYxNDUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATj -Cy1Uh5xMsHjS9LS6OEisXnwpF2piKOwxFxkv1kRyY/BW4DVFng9V8yGocNGKtfQr -C5GG6eUWwLLTBCnLdeoEo3sweTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zApBgNVHQ4EIgQg5ONc3k0++QDOnzWJI4N38lvRq5WSaz/dq8lQJyva894w -KwYDVR0jBCQwIoAg5ONc3k0++QDOnzWJI4N38lvRq5WSaz/dq8lQJyva894wCgYI -KoZIzj0EAwIDSAAwRQIhAKU8aWxhlJ5kiG/cqHkmfFZjY9MoweTEeSeq8ROUVYlK -AiB2nWWrkj7+KzNO4OIwNmCe8nY+JcpIMaKCK4QwhWg9uA== +Yy4xQDA+BgNVBAMTN0NvbnN1bCBBZ2VudCBDQSAyMDY0MTU2MjQwNTAyMjk4ODI0 +MzUyNjUzMDc5MDg1NzcwMjM4ODkwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR1 +6BVRGusIwB0mqbTrnBjEfCvUeChydV3408AG58eJMk89jgQi5x9Z+kK9UF3drmq5 +GRlGhudBgrgEc8wU+bZCo3sweTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zApBgNVHQ4EIgQgmoIDM1aUkGTrzK0Am2eou2/DZWWUiZU1lfCFatJsPnAw +KwYDVR0jBCQwIoAgmoIDM1aUkGTrzK0Am2eou2/DZWWUiZU1lfCFatJsPnAwCgYI +KoZIzj0EAwIDRwAwRAIgcoZwCzJGdL7LFL7Bbp+26OfNvnyhfchSDdN6YEukIVIC +IAd+GbxNZbSqTrIackV1/VkM0y1ZJ8si9IiecRNOKOMi -----END CERTIFICATE----- diff --git a/test/client_certs/rootca.crt b/test/client_certs/rootca.crt index a62c8916e2d5..f57e1cb34f00 100644 --- a/test/client_certs/rootca.crt +++ b/test/client_certs/rootca.crt @@ -1,18 +1,18 @@ -----BEGIN CERTIFICATE----- -MIIC7jCCApSgAwIBAgIRAPQsQxVaOlwVK7QsleZhCuEwCgYIKoZIzj0EAwIwgbkx +MIIC7TCCApSgAwIBAgIRAJtKNACj8KAiBWSSqeYB15EwCgYIKoZIzj0EAwIwgbkx CzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNj bzEaMBgGA1UECRMRMTAxIFNlY29uZCBTdHJlZXQxDjAMBgNVBBETBTk0MTA1MRcw FQYDVQQKEw5IYXNoaUNvcnAgSW5jLjFAMD4GA1UEAxM3Q29uc3VsIEFnZW50IENB -IDMyNDU2MTQ1MjY0NjQ1NDA2NjI5NTM1OTcwMzc3MTUzODA2NjE0NTAeFw0yMjEx -MDExNTE3MzVaFw0yNzEwMzExNTE3MzVaMIG5MQswCQYDVQQGEwJVUzELMAkGA1UE +IDIwNjQxNTYyNDA1MDIyOTg4MjQzNTI2NTMwNzkwODU3NzAyMzg4OTAeFw0yMzEx +MDIxNDA2MDhaFw0yODEwMzExNDA2MDhaMIG5MQswCQYDVQQGEwJVUzELMAkGA1UE CBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGjAYBgNVBAkTETEwMSBTZWNv bmQgU3RyZWV0MQ4wDAYDVQQREwU5NDEwNTEXMBUGA1UEChMOSGFzaGlDb3JwIElu -Yy4xQDA+BgNVBAMTN0NvbnN1bCBBZ2VudCBDQSAzMjQ1NjE0NTI2NDY0NTQwNjYy -OTUzNTk3MDM3NzE1MzgwNjYxNDUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATj -Cy1Uh5xMsHjS9LS6OEisXnwpF2piKOwxFxkv1kRyY/BW4DVFng9V8yGocNGKtfQr -C5GG6eUWwLLTBCnLdeoEo3sweTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw -AwEB/zApBgNVHQ4EIgQg5ONc3k0++QDOnzWJI4N38lvRq5WSaz/dq8lQJyva894w -KwYDVR0jBCQwIoAg5ONc3k0++QDOnzWJI4N38lvRq5WSaz/dq8lQJyva894wCgYI -KoZIzj0EAwIDSAAwRQIhAKU8aWxhlJ5kiG/cqHkmfFZjY9MoweTEeSeq8ROUVYlK -AiB2nWWrkj7+KzNO4OIwNmCe8nY+JcpIMaKCK4QwhWg9uA== +Yy4xQDA+BgNVBAMTN0NvbnN1bCBBZ2VudCBDQSAyMDY0MTU2MjQwNTAyMjk4ODI0 +MzUyNjUzMDc5MDg1NzcwMjM4ODkwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR1 +6BVRGusIwB0mqbTrnBjEfCvUeChydV3408AG58eJMk89jgQi5x9Z+kK9UF3drmq5 +GRlGhudBgrgEc8wU+bZCo3sweTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zApBgNVHQ4EIgQgmoIDM1aUkGTrzK0Am2eou2/DZWWUiZU1lfCFatJsPnAw +KwYDVR0jBCQwIoAgmoIDM1aUkGTrzK0Am2eou2/DZWWUiZU1lfCFatJsPnAwCgYI +KoZIzj0EAwIDRwAwRAIgcoZwCzJGdL7LFL7Bbp+26OfNvnyhfchSDdN6YEukIVIC +IAd+GbxNZbSqTrIackV1/VkM0y1ZJ8si9IiecRNOKOMi -----END CERTIFICATE----- diff --git a/test/client_certs/rootca.key b/test/client_certs/rootca.key index 4493d2f01961..f3b6cb6d57ac 100644 --- a/test/client_certs/rootca.key +++ b/test/client_certs/rootca.key @@ -1,5 +1,5 @@ -----BEGIN EC PRIVATE KEY----- -MHcCAQEEILDGZMNL2mZRmk9LLUm+Ocp2PK31o0BtoTUZ6jqTz8lioAoGCCqGSM49 -AwEHoUQDQgAE4wstVIecTLB40vS0ujhIrF58KRdqYijsMRcZL9ZEcmPwVuA1RZ4P -VfMhqHDRirX0KwuRhunlFsCy0wQpy3XqBA== +MHcCAQEEICDZ+CIUIyHeCulc0Av0afGc6iUrXp6LI+RMCtzXq2f/oAoGCCqGSM49 +AwEHoUQDQgAEdegVURrrCMAdJqm065wYxHwr1HgocnVd+NPABufHiTJPPY4EIucf +WfpCvVBd3a5quRkZRobnQYK4BHPMFPm2Qg== -----END EC PRIVATE KEY----- diff --git a/test/client_certs/server.crt b/test/client_certs/server.crt index cd8a64a1b0b4..a99eec5024d4 100644 --- a/test/client_certs/server.crt +++ b/test/client_certs/server.crt @@ -1,17 +1,17 @@ -----BEGIN CERTIFICATE----- -MIICxTCCAmqgAwIBAgIQQEFFmUhO6yA+4ScqpYgqoTAKBggqhkjOPQQDAjCBuTEL +MIICwzCCAmqgAwIBAgIQJeudmzJEAViQ9sIJfwC8RjAKBggqhkjOPQQDAjCBuTEL MAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv MRowGAYDVQQJExExMDEgU2Vjb25kIFN0cmVldDEOMAwGA1UEERMFOTQxMDUxFzAV BgNVBAoTDkhhc2hpQ29ycCBJbmMuMUAwPgYDVQQDEzdDb25zdWwgQWdlbnQgQ0Eg -MzI0NTYxNDUyNjQ2NDU0MDY2Mjk1MzU5NzAzNzcxNTM4MDY2MTQ1MB4XDTIyMTEw -MTE1MTczNVoXDTIzMTEwMTE1MTczNVowHDEaMBgGA1UEAxMRc2VydmVyLmRjMS5j -b25zdWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATC3nIFymQYpIn4uBxLQS6p -1W3Y2pdhIYwVT9FOrCN5PE14YESYEkPdGuebSSPf7Lblgv9mGywjpYzgDPgk/kPw +MjA2NDE1NjI0MDUwMjI5ODgyNDM1MjY1MzA3OTA4NTc3MDIzODg5MB4XDTIzMTEw +MjE0MDYwOFoXDTI0MTEwMTE0MDYwOFowHDEaMBgGA1UEAxMRc2VydmVyLmRjMS5j +b25zdWwwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT//eDs5STj1a5x5/fneyAA +rZABkljmKLBhEesrLx4ZoSQHEkEW/RlB9d22wW0nde4yTs58M8RnWDVVRghFU8Jv o4HvMIHsMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB -BQUHAwIwDAYDVR0TAQH/BAIwADApBgNVHQ4EIgQgbvG1NZYTXB5wRZNGjgs+hgfT -1j+klGellDDkmXIZRpMwKwYDVR0jBCQwIoAg5ONc3k0++QDOnzWJI4N38lvRq5WS -az/dq8lQJyva894wVQYDVR0RBE4wTIILY29uc3VsLnRlc3SCGXNlcnZlcjAuc2Vy +BQUHAwIwDAYDVR0TAQH/BAIwADApBgNVHQ4EIgQgakV8pQCroFdBBW0TyFgVDbHB +ZFlLvu9sXfk6+xBtqY8wKwYDVR0jBCQwIoAgmoIDM1aUkGTrzK0Am2eou2/DZWWU +iZU1lfCFatJsPnAwVQYDVR0RBE4wTIILY29uc3VsLnRlc3SCGXNlcnZlcjAuc2Vy dmVyLmRjMS5jb25zdWyCEXNlcnZlci5kYzEuY29uc3Vsgglsb2NhbGhvc3SHBH8A -AAEwCgYIKoZIzj0EAwIDSQAwRgIhAIKx/BNuRx1STi9mupvpCFsl6vvTo6eKyvXk -YlMvo3X+AiEA6YTlNvH5+cWaJQORpX+ZI1Eogkl1h0oWNL4+D0lofIo= +AAEwCgYIKoZIzj0EAwIDRwAwRAIgB5HA/sAnp5EWLpo+PjM1SAoU6uiE5trKTBPE +UB5+NOoCICuz1zsVEuCTRo7dbFK5d5+G2gM7dwOU0E5nGFqCW46I -----END CERTIFICATE----- diff --git a/test/client_certs/server.key b/test/client_certs/server.key index 9ef60bc14ebf..9e79d6a32b68 100644 --- a/test/client_certs/server.key +++ b/test/client_certs/server.key @@ -1,5 +1,5 @@ -----BEGIN EC PRIVATE KEY----- -MHcCAQEEIM+Rps/EV1QvlRwMo5IT9HMqWVe1LR5vfeernws0pwo8oAoGCCqGSM49 -AwEHoUQDQgAEwt5yBcpkGKSJ+LgcS0EuqdVt2NqXYSGMFU/RTqwjeTxNeGBEmBJD -3Rrnm0kj3+y25YL/ZhssI6WM4Az4JP5D8A== +MHcCAQEEIDBtgIlMLp68GuAx3GzgvqA6L4pzF7ra4U8KBAeAjYwroAoGCCqGSM49 +AwEHoUQDQgAE//3g7OUk49Wucef353sgAK2QAZJY5iiwYRHrKy8eGaEkBxJBFv0Z +QfXdtsFtJ3XuMk7OfDPEZ1g1VUYIRVPCbw== -----END EC PRIVATE KEY----- diff --git a/test/hostname/Alice.crt b/test/hostname/Alice.crt index c9ce912a6df1..70583b8c8a96 100644 --- a/test/hostname/Alice.crt +++ b/test/hostname/Alice.crt @@ -1,23 +1,24 @@ -----BEGIN CERTIFICATE----- -MIID0zCCArugAwIBAgIBMjANBgkqhkiG9w0BAQ0FADCBmTELMAkGA1UEBhMCVVMx +MIIEEzCCAvugAwIBAgIBNjANBgkqhkiG9w0BAQ0FADCBmTELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC0xvcyBBbmdlbGVzMRkwFwYD VQQKExBIYWhpQ29ycCBUZXN0IENBMQ0wCwYDVQQLEwRUZXN0MREwDwYDVQQDEwhD ZXJ0QXV0aDEiMCAGCSqGSIb3DQEJARYTamFtZXNAaGFzaGljb3JwLmNvbTAgFw0y -MjExMDExNTE2MzhaGA8yMTIyMTAwODE1MTYzOFowgYMxDjAMBgNVBAMMBUFsaWNl +MzExMDIxNDE3MTZaGA8yMTIzMTAwOTE0MTcxNlowgYMxDjAMBgNVBAMMBUFsaWNl MRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzEpMCcGCSqGSIb3DQEJ ARYaZG8tbm90LXJlcGx5QGhhc2hpY29ycC5jb20xEjAQBgNVBAoMCUVuZCBQb2lu dDEQMA4GA1UECwwHVGVzdGluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAKOBOrkFZB7absO9wimOh36sbVtwBkKyNjM86cG07U8QIAHm4WrBBEy1VVme -N6DOV0gSgU70ZufAAx7uFxp5wlf6z1uaVHYT8y7DAFwL3cUqphchR8C+pTPgOikA -3ymDyt6jqUGnnsbcv7/ml/gr8sxTqFIFyxnfevw1JjeyOwnXDwg6DYsL3co+xTNT -igwhP+QGUEsCYuoOZ+jXDbpKLrXsxycjkC7oODuW5Vq4Tv3pZQ3ZFqlbLOg9qYto -xRz15rcY9lBHoZog+dH8Yc29COxe60J6pky6N+pE8/f+NVGRGqa/3W4qunrpNYCj -a4HmrplcnjOne2lWL5qsisGfo00CAwEAAaM4MDYwCQYDVR0TBAIwADALBgNVHQ8E -BAMCBeAwHAYDVR0RBBUwE4IRc2VydmVyLmRjMS5jb25zdWwwDQYJKoZIhvcNAQEN -BQADggEBAJukWnrR9B/oJycWlVI9EV7XEwpsFsCEjpHGNM9ow7pgDUUWXL48IZbe -FtvpwFV86hQmvChdmigPy+DaM/EuXwcxQBJhTHh0qUuQZKdH1erUHtIF8XDVGhLF -VuCKD/Qb+2b/f/UcqrYXHhpov+FGnUB3NGUyRVlUVcxvq9wrtFtuNc/8521P6+L7 -HxI38L7tnltailYW/kuEmLw7mE3U+V7APVkhi4xA2yHK0g+dZcA9m34yezS/WeSI -Yht8DDadWLp8Cf/5RrgaLz66Ik+V3nuDEy4HEFW2anztcsVVz7CP73NOYV4mHcJU -synhHnqDSq1wWY94G9/UFmKAETzHU9I= +ggEBAMJ12Q87/iDyvoGQ15aGtr9D9QlDi0+a+22k68e+uFNJExkdgz08i6diJZLj +OOlHX5w+nQjDtWE4km9hNp20MG1OUCTTGeuoe7e8CtwNrSj4p0eMKvM54pPNB2rB +166vL93dElHSLvjALjGN32lHb1v04xJY4QxBfRK+sihf/X0CdmMlf8ic9GkK6KE3 +neu9uBBMH7tcOSEKOetIwmSIA2vIdRK/dvAC2Y4sfIXgExaqk6aDCLr907ctsoBc ++I7t63PkeXwDsHSJRbJ8vhw568QWCpd5YenVH+RlakJ06QPDSIx4WhHQ1t8KctZQ +OfcBlXkABM8483NG9Pk4+kul5I8CAwEAAaN4MHYwCQYDVR0TBAIwADALBgNVHQ8E +BAMCBeAwHAYDVR0RBBUwE4IRc2VydmVyLmRjMS5jb25zdWwwHQYDVR0OBBYEFAPO +IGFQ8uNu3oQW/CUV5ROCyCE3MB8GA1UdIwQYMBaAFFV/pGmUd2WIZQKufC+r9DEX +i2MBMA0GCSqGSIb3DQEBDQUAA4IBAQCcUbkMg2l3mIbLZNalu4GHOaumCRHbUVtQ +OtienyzhLJ4MyCloRPzFQVk2woTHZl3BbAUO34acU574xebQKStTuY+RZQya0Rb0 +Bua346H4UYq+06TtTNxEzmqauXWZ74QYmkT3qJspzeyGZbYmstzDp7Q8fJbiV1WR +3d9maKP46RmF3vgFHuhYgXs3EwQegyeDzETZhyh1ul2pPz0F9E/zPMQthxvOfu7M +sLzbZ6O2kIGIlRMgsZ6d4Z7jMDqh7w6N08xfO4AtX1Xof17r/xlrQNYocvcpO4T5 +QXrfkKZrAKIlHaTm9WsYlx4Yk0gdRxE9vYa1tE6SomSSUEuuj3tm -----END CERTIFICATE----- diff --git a/test/hostname/Alice.key b/test/hostname/Alice.key index 466daaf56982..34cc9e17ed84 100644 --- a/test/hostname/Alice.key +++ b/test/hostname/Alice.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCjgTq5BWQe2m7D -vcIpjod+rG1bcAZCsjYzPOnBtO1PECAB5uFqwQRMtVVZnjegzldIEoFO9GbnwAMe -7hcaecJX+s9bmlR2E/MuwwBcC93FKqYXIUfAvqUz4DopAN8pg8reo6lBp57G3L+/ -5pf4K/LMU6hSBcsZ33r8NSY3sjsJ1w8IOg2LC93KPsUzU4oMIT/kBlBLAmLqDmfo -1w26Si617McnI5Au6Dg7luVauE796WUN2RapWyzoPamLaMUc9ea3GPZQR6GaIPnR -/GHNvQjsXutCeqZMujfqRPP3/jVRkRqmv91uKrp66TWAo2uB5q6ZXJ4zp3tpVi+a -rIrBn6NNAgMBAAECggEAamKhZNWfKXwS6gXEGeoFO2TR2tbvG+J85aXSqxkf93uU -d+hT73QbahXqrN8HbvgTTm/L9yWK92u2HB/qpG1pCHnHBeFK53Ffn6N9zmZiK/Hu -E8qxtzXUpAZXkWphyc9Y5rgyXufDpbzofuJ5Kx7dYhlkwcnHNtR0Xznt3ft38pQT -gZGA7wDY+ups2May8zGESXd96BOcYRF6PnMEiFDTuzcoSNKEhcuP0ftOvmvO/Vph -Nel0phPT0Le57njjw5wQOJBou0WkxC9GJ/UfOaDfwCC058W1yDKSTSZeZbAoGvjX -Hg9U1DAlfVHv8P0pcquoJbfB1W3+ev5nundM47qO+QKBgQDRduMGkBJ8aji5SOMj -h6xCQEDosSVl6A9Y8H6q5yro0Eu+oD2BdOTdcYGa5Y+lasi0K9uyOuzLnkaF91YB -7+aqSG2CipiQxnOXR1/pWsFD+eGNf2npybbhbi6ik6lqzDm27qAfYJjyrThJWZbE -QihuRgHKwv+Dsa2H2Iqacn+QvwKBgQDH1G29y4YmXMX3iGSiowYcG4Fy/HeWQqR+ -huuMmdEenCpMtujb7GG4MbJA1GgWK6fZhkbcAuTmtPAffq8adqauPgmv21qoHYgg -Fm+2qiSMctRELBxEBc1ym00bu4jISvU7dF26mQ9sTUGcTQI9nOkQKFKOTAYjfSG0 -d+xqZshC8wKBgHzej9aQusR6mlgykF3U+qcAIPHW8QGARu3xaMG/T4A89HqukhwD -sJAmo2nQ4kJtlzp5Tt5AbHuyXj5sxVQgTPVEeiwxLWRZOf18Kjw1wzMf2wt8Yoph -mulmwtxehMfK+bkJJmGuN1+sTfrEMrHK8slSaK0UdDhxCo8KUw5hpZSHAoGAXkXD -eBS6NwLxijPYdjm+uifnzB17NXI/NEnmejBezbgS5JouBQLhnwoi9B7A9CSoTSDh -8Q2Ue5rE5bbYWP286Nrvqv0rKcC05Z5wGZbvIytRJNBCjXzHTdgiaoDwqL1kMCZX -yZ5H/mn8GAbklbie4zaCrAsFolx4ODGTYScYNy0CgYBCFxcTBRCqhQd1Hzp6NNIf -Iqzh21FH+uGfG8LtvYE33IUFasUmdcPKq2ZlItfLrG+bOsxXqsKAwKH+Y/XtX/RA -zySeMr1aIBWRowlNZ3CihnYgJ14IZi2JrvVPfY5UIyWYUm6ykEWOANAICTYMXtKL -hIvXoK+Yj5Kq5ZZIp5cITA== +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDCddkPO/4g8r6B +kNeWhra/Q/UJQ4tPmvttpOvHvrhTSRMZHYM9PIunYiWS4zjpR1+cPp0Iw7VhOJJv +YTadtDBtTlAk0xnrqHu3vArcDa0o+KdHjCrzOeKTzQdqwdeury/d3RJR0i74wC4x +jd9pR29b9OMSWOEMQX0SvrIoX/19AnZjJX/InPRpCuihN53rvbgQTB+7XDkhCjnr +SMJkiANryHUSv3bwAtmOLHyF4BMWqpOmgwi6/dO3LbKAXPiO7etz5Hl8A7B0iUWy +fL4cOevEFgqXeWHp1R/kZWpCdOkDw0iMeFoR0NbfCnLWUDn3AZV5AATPOPNzRvT5 +OPpLpeSPAgMBAAECggEANe/+Lu2TBYyPLt0AD256Tf8JfnJPt9rjFnyCMbtC4UcJ +lxPKjTe3/MuKZH3GEV6MtIfhgsbWDotkgqRSQ9fw/sCUFkK/k8/90O7FjFf2ycB+ +lafZWfGaWSirf/8YVgmdm0pwhGVqRfD4XyJc75Sy3KzGNxaUBZQ8nvBp9iz54KxL +WKPgSQB1uLivRYzvDS+naonBvco4GpOLDbTKin2dYWY7fRWE8UIdaUCzhIioiFLu +AQbf/b6FpDTUG24sWmoGanpseiDtmW+sExA8mX9rorRpa7e5vqj20bchyD5i033D +7aKGoZzdHLnVlJmSxNdKZaDBYDOajaYiMXTE8NXqEQKBgQD+R/BgfukZgpetBqu9 +Mj2BwjAmALX88WH16lAv00SOXPj1VK91K4Y9isbhheW0vFRbcbw7pu6tMrev1sbX +d06/dTQufgiZKoY3agth6tgMNZ/TvDUu/KZU6YoR1W2dkRa9BYhGrVql2WRLt+AV +mDX2c6+AwJFw2/Pg6yqF5wUhAwKBgQDDxmH6PMOPvKVssY4YLn36gZR+VzIxamNg +hK1PSgebQ8SWFm7XVrWUY6NkAK3+6bV42PiyXkwcMs0mvUU9ZAfTH9P+beuo7g97 +3b72Q6IwMZkcLnsEcoKfOopnVZ7Iu045veIS08CYezNCfXQfUqB7UlUCHUls4r5A +enQZkEXqhQKBgFPVlfvKe8GsW6NxKpgDA2JPip5M57NQRfLU4METz2t8XZxM4lgo +FGcf5PgftB8FZG6NrfigzdoOeZ8gmYgaTr0ywBR/+we8jGmircQHsFk+KMafK42l +QJWINbwxeKVVW4DQXSCoMNWzOaz5H4kfGNN7SqaRVqI18k76WZeyFe/PAoGAB1Yv +5cjRK1nOeTxOLunPHswsXG+4GdH612shc486qb7oZxeAH+HH/D+fp+e+nYb0ngrD +hyuxfn0I4yLErYBKKsdOkoJcCoChY+rzdRcjxNqW+k9jnM8NxhnThfvXb35VeCR9 +jGcTGKPFUACTkXjvOq/jL6kZT1NP/eqY3zxg4mECgYBWBojTb8n2hff3iRfWRyp8 +zoyteZrUz6apXM1dWQpmU9Qyu325CXFdMQuGCUBIAWNf8no38ZJvDZUAoLOky1Ni +fMnsVXEi69jRYQRVo2AjV+caBhW6k0KWlFn7mCdyh7bh2WXcvLtUnylc/7bPONyX +gxVKzytFZRegtcqJut742A== -----END PRIVATE KEY----- diff --git a/test/hostname/Betty.crt b/test/hostname/Betty.crt index 3fbeb5fe8b21..a25066b01486 100644 --- a/test/hostname/Betty.crt +++ b/test/hostname/Betty.crt @@ -1,23 +1,25 @@ -----BEGIN CERTIFICATE----- -MIID7DCCAtSgAwIBAgIBNDANBgkqhkiG9w0BAQ0FADCBmTELMAkGA1UEBhMCVVMx +MIIELjCCAxagAwIBAgIBODANBgkqhkiG9w0BAQ0FADCBmTELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC0xvcyBBbmdlbGVzMRkwFwYD VQQKExBIYWhpQ29ycCBUZXN0IENBMQ0wCwYDVQQLEwRUZXN0MREwDwYDVQQDEwhD ZXJ0QXV0aDEiMCAGCSqGSIb3DQEJARYTamFtZXNAaGFzaGljb3JwLmNvbTAgFw0y -MjExMDExNTE2MzhaGA8yMTIyMTAwODE1MTYzOFowgYMxDjAMBgNVBAMMBUJldHR5 +MzExMDIxNDE3MTdaGA8yMTIzMTAwOTE0MTcxN1owgYMxDjAMBgNVBAMMBUJldHR5 MRMwEQYDVQQIDApDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzEpMCcGCSqGSIb3DQEJ ARYaZG8tbm90LXJlcGx5QGhhc2hpY29ycC5jb20xEjAQBgNVBAoMCUVuZCBQb2lu dDEQMA4GA1UECwwHVGVzdGluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBAKQlj8NuFi8jBF3NrU1bUopIfCnJJBVUrITAa4H+m3NiipWh4QZirQctKrf0 -vaG2sZ8UJprESsYhWDyZ/6+U196b1y6KVEU9bvfXbaGEZTKsjnNrKIU90JbBbZvw -3eH1J8bMPkvkzkPrhMn7uO+ng04lorVkQ8tk6i8fzSpYFX8mxeWz0yz6KK1C8Bre -RGtBe2kcMWwCzEdCabE1BwwPLf7wn2vfePdbyc4gxS4OzQcKFRJEb1R9E+l0Gmvx -sJxK/RggPCNeHvD/ypWm69ssddLvdJ76Ut9jUAVKlQLxBb8anHm2w+ybPXlrDfnU -37Bi6QjsgNwH+EUhvjgowc9PLPUCAwEAAaNRME8wCQYDVR0TBAIwADALBgNVHQ8E -BAMCBeAwNQYDVR0RBC4wLIIRc2VydmVyLmRjMi5jb25zdWyCF2JldHR5LnNlcnZl -ci5kYzIuY29uc3VsMA0GCSqGSIb3DQEBDQUAA4IBAQC+qTIIkbk+ekiAnijKw9ae -VdLoMgFoGTUpf/RnNjcHvHlITprQoobdHMmOKV3EXT9zFaUjNOcrUXq7Z5LQozc2 -wHhh5M3FWg2BHQqosePZx+8o5aPJgmbr3upOB9xWQtcEeTh2q+ozA6ZqjVvHQXH9 -k4VOSls0Hzv+SwOsVIul/AKm7gXlr097YxvKhaQNoYdo21eyM6Kk5t6iwYq7u+II -DcvWvMNX4p99bOPv8RfbnnKeLF85i00evZ0VW80TBGJtcBXnEIviuL6lQzZ3H1rt -zr8psCb+iOitfgh0Sv7Zk+zKGlbPc050RGYTjwNcgxnsPoPzm3hPJXZ81erq6w8O +ggEBAKqNlGi1SLBzZFZQ4hK8ZlbPdHtg9iONOp1aMxL+eUs/uzpYJNzn4qo71r8o +EgUbaAP60PVDcdxz1VNxbSL9NPU80/fMevu5lpvRTtf1EQNJqh/FQGDFR52/1j0p +68m3MwpJ0EUlODI98c3E66Un5gGTGcnqNsTXotGWl4zzeY8CLy4ZWo5/ToGafMHT +Bk1s0VDx+g9ROnhMjscV6eLAwkPa0vNQtW1REY6kQ+feEUZPHEEYOEdM89RlPHm9 +U4pkGdXjP9j+lD6DRYyJ8GkSx4cGEsge4Gbn6Ynysd4j8umLZ3u0S7w7S9svEr5l +ZoOMiKI1lXP+0pwDOIEgdVYohncCAwEAAaOBkjCBjzAJBgNVHRMEAjAAMAsGA1Ud +DwQEAwIF4DA1BgNVHREELjAsghFzZXJ2ZXIuZGMyLmNvbnN1bIIXYmV0dHkuc2Vy +dmVyLmRjMi5jb25zdWwwHQYDVR0OBBYEFG/QJlW3De2DxyykpbmmQ+lCcMDqMB8G +A1UdIwQYMBaAFFV/pGmUd2WIZQKufC+r9DEXi2MBMA0GCSqGSIb3DQEBDQUAA4IB +AQA6/VQuwESOX0+v6ejLkHbw/1sER942WhmqIn0zMRIGkvpqJkYfo7uWQUIecpKN +gxrWrxEySpBbo1R/yCTVejWrDBhk29nNY4R6VSU3BrTJaqRbx2d7WoYK5IJm+JCP +G0Al7FjaR08rEiQxnan7pkFMKp6zF9m4DQYPsh+ZjfsV5ObV/y4f8o7Sq5l96yII +OwWErws9mTcjN20OM28zcy5H2VyJXegEMhkxz+4n5S7UowDpTUua0ytATtIZ/KXW +GDBEaA+p9Uz6nK01poEuKl4cWwADEjUJK2Kjvm7jVJP1ifrR7McBWcGksyto94Zh +lv3F4jH5AaQ25kE2WDnwxRjE -----END CERTIFICATE----- diff --git a/test/hostname/Betty.key b/test/hostname/Betty.key index d97e32c84825..a5cbe308370f 100644 --- a/test/hostname/Betty.key +++ b/test/hostname/Betty.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCkJY/DbhYvIwRd -za1NW1KKSHwpySQVVKyEwGuB/ptzYoqVoeEGYq0HLSq39L2htrGfFCaaxErGIVg8 -mf+vlNfem9cuilRFPW73122hhGUyrI5zayiFPdCWwW2b8N3h9SfGzD5L5M5D64TJ -+7jvp4NOJaK1ZEPLZOovH80qWBV/JsXls9Ms+iitQvAa3kRrQXtpHDFsAsxHQmmx -NQcMDy3+8J9r33j3W8nOIMUuDs0HChUSRG9UfRPpdBpr8bCcSv0YIDwjXh7w/8qV -puvbLHXS73Se+lLfY1AFSpUC8QW/Gpx5tsPsmz15aw351N+wYukI7IDcB/hFIb44 -KMHPTyz1AgMBAAECggEAAKOAxrLj9TT+rFrDhNyJGq6jhQoaUNbugOm6wVu7QRyu -C10A4iR6JeAAHY0fO8TZNhQ+/jUrUVAJ5tp2izlaCayzjqPNJiPSDbbR32IDfsn7 -F+nf03zlFeEUyxmJ03o/uF9NEsCGKO9+qcaH9q7BLQmqc2g7d0wiOSK3iqWjF8aO -QCvjtbmdZasefRD42ouhVkWBKcuEy2ATqV4l8M1Ne/iVDhExVTCshYjpqPDoBNwm -19H0k+VRoUFVQNG1t7W31E/R5Oo2p6Xu3heevqVwb/2cX1c1RDJnDEZZH1/LimN1 -qDvcl8YxEhqlMjYmraeob8aTbOaByNfGK5kS9cQnwQKBgQDOx5Avo4mG2F779YSV -oVpabAfbl9t+4hsZosIoHRgUMp5uRnxyV11qoXw61Wq08aRAjUJvXeJDP/9nceSg -4Zptlm7BOnHrL1ksho+Dx7T0qNBTiiXWe24gx5RHOyYm4LrtHujXM46nxuWG+qRU -MX19GBHyrnb91zoEcmXR7eK3JQKBgQDLOBm4AJSmkRwEBcQtxGW9svLE9psqXUBf -rEFee0Ueiv/YJiRhmPWgOED06KMhWn858aI6VxXFCt+bu9hRkRdsVuB1Jw7EdcQ3 -oi2oD0Q4c1wBASw4uJ6Z+w5AARlDE5TY0sEMNcBxQl4Sr4f/JDSjuaAgRbp0jnlH -9LNRa9ldkQKBgQC9b4Zgnmn353HdUmhMzK2B+UaZnt2vuGUrbziAl2bf2h/a1yhb -eD5U2ex92dcQPfBEUyVx8YjAI3lQw764xPY9P3vn+iszUwVXDU+dYvAc1CtG3WEc -xad20GC/gSjKpUeaxJ57yPgALO9KYYT6vPxCBjMrKTpKA0tbl5JAaLczIQKBgQDC -MuZA9C0Zz+nZ3jjPE7O2SF++4Xr+TQbLZq1BQMOYoHRFdo2lxqpTZe6NHBNoODcE -hGjnH3lqRy3QgP4DVIfxvEPbMGvoSjIsiArhY1VqLLNrMle0DJljxIqll2cwtnGz -khNxO5yfnzCO4rcvlsXHAAiJTpkT8WLs5GbIFCwwQQKBgDscsFXLFX2BCB1ouscx -yL4CE10d3NM3adODHgRWZ08YxbxG4iwX+NdfKV//tHBsyGzkDAKdWfw7m5ADf900 -l7+Re3rwEbhFKm5Adlj/BYydyrEbFJWE7cwejugJLX7+v0XsiqrnNSt3hGdGbgrN -sRMcxtzUUP89jbpLrYwg5rKX +MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCqjZRotUiwc2RW +UOISvGZWz3R7YPYjjTqdWjMS/nlLP7s6WCTc5+KqO9a/KBIFG2gD+tD1Q3Hcc9VT +cW0i/TT1PNP3zHr7uZab0U7X9REDSaofxUBgxUedv9Y9KevJtzMKSdBFJTgyPfHN +xOulJ+YBkxnJ6jbE16LRlpeM83mPAi8uGVqOf06BmnzB0wZNbNFQ8foPUTp4TI7H +FeniwMJD2tLzULVtURGOpEPn3hFGTxxBGDhHTPPUZTx5vVOKZBnV4z/Y/pQ+g0WM +ifBpEseHBhLIHuBm5+mJ8rHeI/Lpi2d7tEu8O0vbLxK+ZWaDjIiiNZVz/tKcAziB +IHVWKIZ3AgMBAAECggEAFUWfUwf5Tvi1dQaVi9yvrvglARZw3LJKs0GCyUWv/zCt +u3Mu9dZ+MNlRyXnH9ZcbfBOWaGDHHMXdv5CQGiMWrdeuYGPCmw7kt/59JPZN7ukL +LPc/NlKkwgohQHOwEvKkjQ3zygwAXFPZit6avXiieWPNfZ+WwSpcBmQP9uaPLMTW +XfDrU+5V9W+N3Ps5NffkDoq+dU43g3OQXFuxIVYJT+v8aqol4DaF2gZ+0nne2jiC +QOYqa+/XGf3ssLMXoYUwk4QPaVRQ4qK5EUtjx/FW3+kF+fPe9hGlBRG6o+PDTtaq +Y+HkLUm0bNQeWwD85x0cc5DeWmVLWhCHDkHhLlmGMQKBgQDvc3kCm0Ab2AXISsvP +H3KZy0WwvwwjxNlA9yhbVtZc27gu9Vp9QuTbondQgoCQnkYPRswKKSNEHaQOFh1D +WHs7W0tk7RXUxrNjoRcyMstyLyXCFWSN/Va9IwJ+C89HVRvvjQA4rjx0ChigmRXF +bXh7UjRVax84v95iHz45oqxWCwKBgQC2Vx4UhoS6p+eovCVmnyENKmKH0wk+fHvE +ExLnpc+hKhVZzwdNc4IhvG9R8seBp94RAUzD4ZWED4rqaGR8CaurSCZjrbfyTMrR +cgrLIuN2oJoKEzHOT73My3K/k/5hde6Fkf2r+pTegJTPwPxzC13qVuqT7fNG8qJ0 +FE8dcKDwxQKBgQC/K97qAM8fK8n6DhVHyOCy/sImCXGEwS1+m5Uhz2OXgWg8PXDA +Xv7eh4hgw8AnNeXTXn+agRuBz3RiNq+oS+UfD5VS/6IVXYptOXiOgFVDVXb8zB2a +6y8sE95yibU0SzPhfh42Io1rS4A7/9yM4gh11Lypkbu8kBrZFf6U/1Y93wKBgQCr +mzvtF1jtjr5guIn+lf72NBC9QeluTJvywfzF1PCe/ktP1Z9Kzk4H0B94oaQQK1u8 +51tG8xTTUAluaUdA0Z0mO2Yd482+FXXAPrNX0QMAj0/J8ZyrTbMUfdkF4pPDR8lv +HiH+7HuVGLB1AmzVHTqLJLfq90RBXnN0CfUXgPuG/QKBgQCaZgAERj8LTu6a43YB +s257Las2njADkSurWRDBqEz+lcxjpsPqZV7mguVrjWlXFmw2ztGbqIOG4gHAHFB8 +54fkRyHMORuPCGZ/wdh9xJtmsgunhA9caPADgoNbm39Ex2sKkAjk/DuqStAPm+Tc +8BaDnfawKGImBgocxWo4xDUyIg== -----END PRIVATE KEY----- diff --git a/test/hostname/Bob.crt b/test/hostname/Bob.crt index 5f96a5dbee59..019030277798 100644 --- a/test/hostname/Bob.crt +++ b/test/hostname/Bob.crt @@ -1,23 +1,25 @@ -----BEGIN CERTIFICATE----- -MIID6DCCAtCgAwIBAgIBMzANBgkqhkiG9w0BAQ0FADCBmTELMAkGA1UEBhMCVVMx +MIIEKjCCAxKgAwIBAgIBNzANBgkqhkiG9w0BAQ0FADCBmTELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC0xvcyBBbmdlbGVzMRkwFwYD VQQKExBIYWhpQ29ycCBUZXN0IENBMQ0wCwYDVQQLEwRUZXN0MREwDwYDVQQDEwhD ZXJ0QXV0aDEiMCAGCSqGSIb3DQEJARYTamFtZXNAaGFzaGljb3JwLmNvbTAgFw0y -MjExMDExNTE2MzhaGA8yMTIyMTAwODE1MTYzOFowgYExDDAKBgNVBAMMA0JvYjET +MzExMDIxNDE3MTdaGA8yMTIzMTAwOTE0MTcxN1owgYExDDAKBgNVBAMMA0JvYjET MBEGA1UECAwKQ2FsaWZvcm5pYTELMAkGA1UEBhMCVVMxKTAnBgkqhkiG9w0BCQEW GmRvLW5vdC1yZXBseUBoYXNoaWNvcnAuY29tMRIwEAYDVQQKDAlFbmQgUG9pbnQx EDAOBgNVBAsMB1Rlc3RpbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQC34ozQD0NWzSZMzapl2NFpOZaYNcO14xEClUZsr+w6MwShUDtfumEc6IHFl/FG -WHVgVluhDlC/OhDBIYAojzHCqE5q76sQyzjvoPP9KDB1lPBFOh1CELwj7vLsbjXn -LTw8bnrPQ8pA7va5d9T1BtAWIiu6IA//YCwhJCKCgUbUascdBWtoH7jgFsYhDC9p -Bca3ix/Tm2gbdfu3sbAaDGLDUnh63oWg/wXJcaMbusXuVyifPencBxdJALf1UX8A -ohV7xqcrLPRvkMX4eR0LSSuSZbk/iiwNGy8T9mrr1Iq2LUorobWzISJEPkMOIgDD -Up43o7kgV3A6RLsGERY1cZzPAgMBAAGjTzBNMAkGA1UdEwQCMAAwCwYDVR0PBAQD -AgXgMDMGA1UdEQQsMCqCEXNlcnZlci5kYzEuY29uc3VsghVib2Iuc2VydmVyLmRj -MS5jb25zdWwwDQYJKoZIhvcNAQENBQADggEBAJvwWyA2Eg/B8Um0dAIjaibW4/Mi -2Zh4SOFqUlD7waDqqR6Nx0k4iUuOOUULGNxQI1TKcrnqYBuGJjXkpQ30GnSD014c -5n3X4ebZ1spX/3dn994vEx1anfF7xxERqIvmeKFJmJMS2zIAzvrcQ9bBEuICMdf5 -Iz/Z2h4CPYXmm8Lt7TwqamO+CuU5ekScSLSn2AAomYIuYQZ4KfqeocFeOuo7bWtN -BcWcRwE1FXrhVj1reNXLwkSQAjnhTOGnepy9StntlHHtEMkX1WF9CqwQg7rgvJ1H -pOV9ijfSDrbQqEKTQ+4alGPi3Hk2Agzgv1Hxc3qTmTdmoNweviktvlL58dQ= +AQC+03P5VbpuXbEqIE50XqovdLOvevcDR0JD4u5msdPSr3icZJRQDkpWzFEDzTx9 +yt31M2M+q1i3OE5hpjY+X5b3Fxl8oqCKwdAokBvI4Ban1c4rHYFIiXrMUgBz/rWo +og9nBKU5Wo67kfwUYK2UR+6w5DmeVQj181bspAwynCYMnMfa1zHPfWrw21IPVGiD +yWZcG+jd7iYuQpVfICy17Vdoor6Jq5sWthSNFUZD7zNo2W7vRRnuH6ooevmvOreU +VQZjMhUhTgODlNXMkKSXuicD0uyIZ1dFx7pIB7PGmtMxF15fzBYrBe4BqTFricL2 +UsBbUta7qz/pR/H2RzK0eE9pAgMBAAGjgZAwgY0wCQYDVR0TBAIwADALBgNVHQ8E +BAMCBeAwMwYDVR0RBCwwKoIRc2VydmVyLmRjMS5jb25zdWyCFWJvYi5zZXJ2ZXIu +ZGMxLmNvbnN1bDAdBgNVHQ4EFgQUQUj5bnFpu96q1GEXeMsYg1bVAbowHwYDVR0j +BBgwFoAUVX+kaZR3ZYhlAq58L6v0MReLYwEwDQYJKoZIhvcNAQENBQADggEBACuN +aAKSUX1zp1jXk1sUoyE5bLs/d3UUT5p68SiXK0McnAk+c23gbw6FQaaFNWVVdWI7 +xhteOvqTPiMTXfOq4t7jU2KnbNZkukthzH1b/OFblM1toO4s9I2jQ9DbxTkWlg6c +f81xqrLwD77Jd327WSrFwCUPC0+vDajASz2yEPnFPeeQ0o4qp44BCUFRkRATJ9Ij +Phh7O6LskRkZnkMDdCtaYyiEH8fgQLQRrPMFDVbJsdFtaHDdAVVWM7nM5Oi+K8IH +wRVZo0s1vl++tHmHNJXveNCGJ18ql2pyDyJs18LlX2tiotMepv5dGjS7oLQ7Bc+o +P2/pkGPk+B1dNVkZzNg= -----END CERTIFICATE----- diff --git a/test/hostname/Bob.key b/test/hostname/Bob.key index 32cd0c96d561..a70830f5c8e4 100644 --- a/test/hostname/Bob.key +++ b/test/hostname/Bob.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC34ozQD0NWzSZM -zapl2NFpOZaYNcO14xEClUZsr+w6MwShUDtfumEc6IHFl/FGWHVgVluhDlC/OhDB -IYAojzHCqE5q76sQyzjvoPP9KDB1lPBFOh1CELwj7vLsbjXnLTw8bnrPQ8pA7va5 -d9T1BtAWIiu6IA//YCwhJCKCgUbUascdBWtoH7jgFsYhDC9pBca3ix/Tm2gbdfu3 -sbAaDGLDUnh63oWg/wXJcaMbusXuVyifPencBxdJALf1UX8AohV7xqcrLPRvkMX4 -eR0LSSuSZbk/iiwNGy8T9mrr1Iq2LUorobWzISJEPkMOIgDDUp43o7kgV3A6RLsG -ERY1cZzPAgMBAAECggEBAJOKi0FFfdpfsKNfQaGGXj/3nQVz3hxKnJNeAquiXAA2 -fziPj5Q3j0QKqlVInKa8wzERGWQYgGFuzZKotpPUkTCGqqTSuIc5B+39TseJP5iY -cFCbWG5xzwNl7jQWGdnrSbGTU6aJ1fZTxlL5+zy+wqd/s2Yb47ocCExvGeFsqNA1 -oAeCK961KfEjf4qDJHNP/DjdfdJdFCDxydtX4/1zTEfGV3TQj3P0nuwU60nkpJPT -LvNXwoxyu0EgSkMP3RUjZ6LHCB9eyeRZYZ3wBKmoudIudVsl0mS8wmg8GfhBpEGI -2vqVaS+631oSf0IIuIyEUIcQuU9l7Am4QAAn3YTyKkECgYEA48abEEQPGgNP9Ng1 -B6/VZAx2bghLMKtdeq+z1At3NrFNOtaooVnIeCQo0xAZK0D4aLsvTAJmvQ8cU0zg -qujSQc7uF82eCTJurQYKQjAx7w4Bcm18ylL1ovxQUCQzdneqv6P5po0kKn1Ba9ov -E1mWyR04mVUvy3EUajyteNnQ05UCgYEAzqupAXDxEfWtJeM20IcyuXo7kfmbgkPc -oOdsWyeXHHAGuXpriknDhzdHX+wVmLBK1YODY/42BywCe57ZcKLtyv+xcWJGtGLH -eimc/qPgV8QbpHEY4hWtPlRV+r51g54jrsXkaLOygVqMtISR276TdWS5QB6BcHFN -jnoh2BsYFdMCgYEA3Oh88XygjOETheq/G9JsClmP7s16Zxx8UAXiSdBI8bFprpwL -9lkGdYbUVUdysaGUiraoe3aEv+3M0flomDmv2gVgo5NXJ6JS9to5ztHBTBFwU9Ne -STfGZimBlwhVJRuQbccR1Hdk0RSkA38bUw/7jtgZUZTuAsiMPTDWKbROtTUCgYEA -rHLmcfJo5WCHWy7txTCa7dOFs3eBAEBZ79VLQACYAb2kjs4Mv/Zu9fv1TZ/0IVUx -DFpRn3U2ZeOeKsLQk0EQhKu4x3CGqOwnoNLqUjwx7WoQ2rUYW0ZVKcY7fB/CdNHW -2nX78jXHhFInSFW6U48BAhrKzSrnPQj9+x4D8YwiG8sCgYBs/gmj1JDEDcyptPTy -DpyAQ9KsgA68mEaQW4dOnydyzR4lxq8ujnED8WiDTrejvh1XcJquDFP/82Dg+Df+ -5XvXH885YZh/yNqI+rJ3zYkjEFZEK3eKJFeDKq3a6EDIJMSpnfdR170V+Db2T0JW -44Qe+CefzX8Mq7kg+D0YTgGOjA== +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC+03P5VbpuXbEq +IE50XqovdLOvevcDR0JD4u5msdPSr3icZJRQDkpWzFEDzTx9yt31M2M+q1i3OE5h +pjY+X5b3Fxl8oqCKwdAokBvI4Ban1c4rHYFIiXrMUgBz/rWoog9nBKU5Wo67kfwU +YK2UR+6w5DmeVQj181bspAwynCYMnMfa1zHPfWrw21IPVGiDyWZcG+jd7iYuQpVf +ICy17Vdoor6Jq5sWthSNFUZD7zNo2W7vRRnuH6ooevmvOreUVQZjMhUhTgODlNXM +kKSXuicD0uyIZ1dFx7pIB7PGmtMxF15fzBYrBe4BqTFricL2UsBbUta7qz/pR/H2 +RzK0eE9pAgMBAAECggEAMtd5vcOmgUM7MaMb5AtYwn4QZb+YUmpI8Hdk1z2n1ylj +NB/kGBRGoCudpiqnZEiJrIu9dHQIlgBNedzj9OhY+4pPAxL9PRr4T+ZdUL7Lqnnf +jUM2L9JZQljSwBTr53sOKX9mWgqTnsv9YpyDgs9LfBvCcjnrwkPMNA5dJZrO1Gr3 +QWwlS35Uzoyw7z/abTfkP87ojAJbH2f6O5XleBdi4dLFWoec7sj1Xkj5RmhEf+gx +SJelY33LsPo0apI2YKKjBX4TQ/lvi2AQ/aN3VFBQp+IOfZmPpnlMm6mgagggaa81 +JekSBaTDhHIHH0z6NlKJAJWsW2Vk29e7CEGXAQMjZQKBgQDmF93E0kQqxsbws2Of +ycS/bsfA7vKyH2BRPx3MpsnmlLCD8+kZIBOY+o2YPlK7kzM7A91051jbgv96bLUP +4PJJ6GY71Ci2SydRGvDmITHMMnkDqdrrPYmtbWxGfpMyjmneHm03qhz1RZF3XyXW +SuPQdf3Pp3TFlazxSUbVmoUdjwKBgQDUT8KnzPqdB8tYdexj9XcAvwp2nyN2QsS+ +YHzPfBpZ5QgZ0A2rSaIzr0pUM5h3ie2scCnZByPyilxST8+E6W1En0Hj21H3g3hC +eSvn7aGSklOk0R45c0yuUZvo2fH7IJ+XBcT4lxD61AbI4Xm0Hel8VYoWaeHR8E+W +R4HVVFQ3hwKBgQC8ATI+eQQj46l30UwMqsNtG6px9YwuiL6dhDHoHzwHgOS93JVQ +50m8DLWXeQ0GoR8SEHVp6QJM0jvHn31OTSILy62FIzRkxwGIHrhJgUP8Mh15Jddv +sSeGokr/SrshawYL7NaWzhO9QSu72u3CrAx7L33Ep3IdY9AckyAitpAf9wKBgGhD +92ui7dzabBG4b+wzK0sxhvj0dFzqs2ZvSjw3TVWiddT/aQcatU6+ojkx0Ym7Mf7C +YrrTl+LP8kD2Mwqp/GB7+cbl+Z4dcZzrlxVijTvHIs7JaBd8uUbOi0vSZNUYk2d+ +jNosjkkwgVh76uH64qSN+a/CNgV9CAjcezWCIY3XAoGBANdZR45FezT7bWp6Mfs9 +5s7RjYKC0Yp0hl2elV9I8IgFGu7faV64OodAVxhfLhzORIRrz2SSAHRDaJ4h1T0o +VfE8bflu4i/KmvYLc5TpKUeSKxxJGmfj/BJKiA/xMCVo9AEFme2jv0pMFHVPiBBa +GRqHbtRPZnaQim9+qGmWiBWc -----END PRIVATE KEY----- diff --git a/test/hostname/Bonnie.crt b/test/hostname/Bonnie.crt index 4e71f5983824..0c856e3be569 100644 --- a/test/hostname/Bonnie.crt +++ b/test/hostname/Bonnie.crt @@ -1,24 +1,25 @@ -----BEGIN CERTIFICATE----- -MIID7jCCAtagAwIBAgIBNTANBgkqhkiG9w0BAQ0FADCBmTELMAkGA1UEBhMCVVMx +MIIEMDCCAxigAwIBAgIBOTANBgkqhkiG9w0BAQ0FADCBmTELMAkGA1UEBhMCVVMx EzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC0xvcyBBbmdlbGVzMRkwFwYD VQQKExBIYWhpQ29ycCBUZXN0IENBMQ0wCwYDVQQLEwRUZXN0MREwDwYDVQQDEwhD ZXJ0QXV0aDEiMCAGCSqGSIb3DQEJARYTamFtZXNAaGFzaGljb3JwLmNvbTAgFw0y -MjExMDExNTE2MzlaGA8yMTIyMTAwODE1MTYzOVowgYQxDzANBgNVBAMMBkJvbm5p +MzExMDIxNDE3MTdaGA8yMTIzMTAwOTE0MTcxN1owgYQxDzANBgNVBAMMBkJvbm5p ZTETMBEGA1UECAwKQ2FsaWZvcm5pYTELMAkGA1UEBhMCVVMxKTAnBgkqhkiG9w0B CQEWGmRvLW5vdC1yZXBseUBoYXNoaWNvcnAuY29tMRIwEAYDVQQKDAlFbmQgUG9p bnQxEDAOBgNVBAsMB1Rlc3RpbmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQDCpPFR+nO9czgQT1VLY/uCZ1O35ighW+pCuXJNSnO8xPtesXpdpV7HfijD -2G9zza5kxC3Gvg9Lh2Hj+6R1mTxJj15vqhVdj61hQrK/qbYh2NkH35BQP+z92i8x -3qp0syzCZ+Q/0CdtawZQa4milVCGtwrsBOnETCN0Qh1AzR2mJVpB7TPE49R9BbFy -GZEWlpQ1YKJu7lYDN+YFlgI5sOcVZYI9NjT+mW+RS5Zrv0nFZFsmlYuXUN+mGXmr -0rOS0Mdl1jr06EBJTxXImyfuostb8dSAJ9E7nhv5VMYrdp0ooS3XSbOxparOkh4j -2HwWY8Sv5AKqoTPjRceN/a9n7+JFAgMBAAGjUjBQMAkGA1UdEwQCMAAwCwYDVR0P -BAQDAgXgMDYGA1UdEQQvMC2CEXNlcnZlci5kYzMuY29uc3Vsghhib25uaWUuc2Vy -dmVyLmRjMy5jb25zdWwwDQYJKoZIhvcNAQENBQADggEBABCfAENvsVaDNL88NfYF -u/C3FPjse/gIcDQYpXqTUpzbUaSZwaeV15RZEvDSu5JlFZzjW8ABaiM5+IYX3l5+ -bILkEJlVeL5VYDFAy2IymwmFXozlbAhE9kEdcubm3DCLsZtK+byP8iUCEaAu43Cr -lxny4BOsfPK+37/ojNK36DlRruUmxcuWN7Cwbg9tHCnkvZOd8e/iMY8/jPw7pzgM -TjnpahD9veEtWsTtmYpe6CiJ3JmliIeGlhlflAoVw6cw1pwgueDDiRfuFfJcsJMI -BQsSUd4DRVcgc30PgsK9cotXrCXjnFnmM7cKZUa0/JJ+8ZpoERN+6qybSZSIGns/ -tww= +AoIBAQC8j0vJnP8Zhlhirq5DDOipl82Xl/Rwu+4gV+inNGc2EtUKJ+luzYQHBF85 +UqK3qJKM1ihKZ3QmAN5j4yxRusJgWAta/nfP2eR9F6DGJg65+7nBJzgfU/bU3/bT +p5LLFYx2C1WSDfG1sKkMEAR+ZjLacBzvgFATP4PSQzH+3XSLdaAw0B0J3yBtgFNX +LtgsXzEoAwZckNbV7ww2Jm3fI7ajQL9VCjNokbymeOH8+IA7go3nLcBOWK8OhB9W +ihOk7i/3D9ieySitEg7gQtl1OIfPW39Hj7Zypa+3v+8/ns0j3InztemvF35k2daa +1+/j/VpaPQaqEVvArGcKwYfKtt19AgMBAAGjgZMwgZAwCQYDVR0TBAIwADALBgNV +HQ8EBAMCBeAwNgYDVR0RBC8wLYIRc2VydmVyLmRjMy5jb25zdWyCGGJvbm5pZS5z +ZXJ2ZXIuZGMzLmNvbnN1bDAdBgNVHQ4EFgQU+JiThRiJsAqfmGVNnfKktsnM63ww +HwYDVR0jBBgwFoAUVX+kaZR3ZYhlAq58L6v0MReLYwEwDQYJKoZIhvcNAQENBQAD +ggEBAJQsSUep4bULTESb8C/nS4et9GW1e8yawiRlKJfHWURJRdQynJLSlc0QZk8i +Qj0QFeAFUD1TjbncJFgEgm8mTnNLiFl1jzvAFcqpGySv7uE1ET6GtP3TEnm81eut +rXx3gMxXoPQuPbtEfOqruV5sKp/MLUJ21NBFxpWIThQRALAoRZnhUUcIcGOwD3HM +8U6YC8sLN7M1Hes6VeNpKQ+oJqJMlofiCBkMHpg1qp+KZowdU06PDaDMpTi2ofV8 +8WvpUqDHPP1C1YvrpdvBSBG+bAPgPbgfUe5M2Q9dWTLBQ0TbXP/noX+hyRSVN5Oz +NqX2f02UOjgp0PkyCSq8Y3nHuxo= -----END CERTIFICATE----- diff --git a/test/hostname/Bonnie.key b/test/hostname/Bonnie.key index da4909f39ef4..235f0481fcc8 100644 --- a/test/hostname/Bonnie.key +++ b/test/hostname/Bonnie.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDCpPFR+nO9czgQ -T1VLY/uCZ1O35ighW+pCuXJNSnO8xPtesXpdpV7HfijD2G9zza5kxC3Gvg9Lh2Hj -+6R1mTxJj15vqhVdj61hQrK/qbYh2NkH35BQP+z92i8x3qp0syzCZ+Q/0CdtawZQ -a4milVCGtwrsBOnETCN0Qh1AzR2mJVpB7TPE49R9BbFyGZEWlpQ1YKJu7lYDN+YF -lgI5sOcVZYI9NjT+mW+RS5Zrv0nFZFsmlYuXUN+mGXmr0rOS0Mdl1jr06EBJTxXI -myfuostb8dSAJ9E7nhv5VMYrdp0ooS3XSbOxparOkh4j2HwWY8Sv5AKqoTPjRceN -/a9n7+JFAgMBAAECggEAJv42He8nipdvbs0F0FGaTBh5DAk+ltg8CNvvyw4UO4fW -t7SkR+heIWbjscBFK5TTz/oBFaRzmfToJmz+GFT3X+Ep0QLovtKOsEJVXtIX25X+ -fHZMCdeUmZJBDCOIUFKor9VyQ1pm26OqIyg37WsuM56twHSHhDygiaTJCXdN7j+J -3JSQTUXIQI4pjwMf7GmvwaxrbOI+luxyZioXPtUbnB6fmTXrGYykuif5TV+l+C25 -QeH/nvcksJ/TnGbKFbdVVQJRSKl4oc4X3oHTujEIrn06/oQ98OGu2NTyuBTcmOGe -tkwjbMLabiPguPUml6xHh4U63oDnCVHirCrvUjlabQKBgQDpIgomMCQ7jZpkC2WO -dvtHiJPlqQAwsuhy8RziS+FKp6MZ/OcpKtTE8attxrZoEyPN9N9o4hsX2soKkWyc -IJZrppSBeBxyxAJqXXVfa1ATW4dvwCr1SUZIxqHchQFjtzsh1rTyqesCmPFvFL3w -EEIBRiadJtzQjjvbSTSXKelunwKBgQDVvHRDV60uJzJ7BmeYexzJscS9rwaMjoLI -m//4dv9u2wa3k10ZSrJQDjCT3KVzUR1x9kYp3VffAJcqYoRiHegrgBZfeziyr1gk -KbwnUN1lluPDp9f1XuZ70FTR9WW1p8vMtfFIBcEbgZHPFEr4p8KV7RuqbcHmsP8o -47VkL+UYmwKBgQDLMekIqdMauOwFIM3OYzPWgFrvw+Ivj+/8Jt0W/C4L5JrLDtvn -zLYQRdc14gmgInaFj1Wd09zraL3Kgj/YwKp6f4FWavrYqLC2RmkD1sO/a3pbU3Hd -wpTo33+6dY7le5Glh77E9oaoB+f++mQmNfVhqOQE+xdhC2duVJrq2hPkXwKBgGic -5db0OfpmCwo2F0yFrZB25xHkcfMn6ZFg8YdeTyWmJIKDqUSwz9fpKhOlIoHvyNa3 -sJ3bDaBDvLltINiZRMLN3aV8PUMQGbcRils/9C0+Dlr8cvJRMcSWMn3Ve6PO7ixT -PTaAQoVBBOnzR8Ku8cnKFQl00Twlk64izeysmJhTAoGADeHDHJ9SZGXsWx4qfAP3 -w/X0Z78hjj03F1wZy/WCT0fBo2ZPwgNvJycihs5nevvOxyh0T4kU9LcJpP4Xh9uy -xvcHXhfm730ihVVvrSbcqKipVtUQVQjKNkgi3LesUU6fVtR3cYeZjgFX8gK7qlyh -r/DA0g7GHp+pHoQ/koo15Io= +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC8j0vJnP8Zhlhi +rq5DDOipl82Xl/Rwu+4gV+inNGc2EtUKJ+luzYQHBF85UqK3qJKM1ihKZ3QmAN5j +4yxRusJgWAta/nfP2eR9F6DGJg65+7nBJzgfU/bU3/bTp5LLFYx2C1WSDfG1sKkM +EAR+ZjLacBzvgFATP4PSQzH+3XSLdaAw0B0J3yBtgFNXLtgsXzEoAwZckNbV7ww2 +Jm3fI7ajQL9VCjNokbymeOH8+IA7go3nLcBOWK8OhB9WihOk7i/3D9ieySitEg7g +Qtl1OIfPW39Hj7Zypa+3v+8/ns0j3InztemvF35k2daa1+/j/VpaPQaqEVvArGcK +wYfKtt19AgMBAAECggEAUdMfMMDjxJhTj5M9BNS7vCina3Lh/O/YkImFaNWpOkJm +147lUhN2CTOA/Reai/dnjR08A7msIfe7if4hk9/nDLb4SoblyDlGWXBg8MvAFT4i +6CpUROgDU3JTIprz7RQPTYRyoDxT2SPt39GtmYpQ5BDFxbrZRNkJo7tMHUzNj9x9 +1v2EJEmryuU5/2Q+gm4GKfjWVBAY245Emax2O6BIZ6/JWw5RGuO34ze3FrNlPHx+ +mfwpvwoelH935Jmw5mLm5UDX1xUTHGOxgOmzFc1dtUPpD7IjtXRAQFhkFlScLXAE +ZI4vcqmHq88KCNuFMQuYAlJNxH6UonXeFbUqstmiQwKBgQD3qWzHfgGAG607KQ5p +B5qv4KLzaIRy6o0deiaEak4gSpzti3RMBUtylW+44GG3vcj88Ve8WKzC6tWtG20Q +47hELeTXlD9nfS//n6dVpG3D8dWsvSW35ukX8H7U3aa1w3U2eJ+OL3stVl2q6Xf+ +O/Q8HapE6TydpEpDMKV5nEdKcwKBgQDC6HnHQ89UvxOPZC70XqW5KkFV4qYn34a/ +X4fQW/Z+AsNlhuxElpAExehlijlEN/uw4nCTIwAKfLKNSfuv3PWxPP0tH1wHigIr +S7j7RnzqO7pA6+GUuiPe2EZlhpg+GdM5kbP72WbDaM8xilIs9m18LX4qO1I5KErb +amzHHACMTwKBgCSwn+HqA/TjpMVH7s+Whc8ae2mOCVkw8Fj2mLAzQ4G7LAZxC3ib +rDK8esGr1C4xWo5GftXzWRzDR4aOspi287x+BBH/72i4fhzjnRmt82j88cfWebkF +53BZe6CzeZgh7cJ1GkYpOJld2yCP1+v9G9CwIGJ3HzjHdwz/LvSWN2WLAoGAVmdy +3PhdqEcQp8eU3TY8J2rpDebtG84G0T3LWn36NwCImLCIext3+vW1QZZWLrzWsiKg +H0or0XpYOTRsBBljPdA4uFEnnhv7PDBUb+hepgQWXIN1PFaMYlTkWEujoBwYvHOw +I1zMJqKG/4I/Tbls7djJDnW/zKDlFoIGePob8BcCgYBFBatrej1BT0H3FDHbN967 +bt3AmxO6xLY3lB1rxqgBmoGpAvF3Prbus1fKgRezIM3zkuLxlCv7KbQVRbL3fx2H +n8jM34Gno/RPFtYULva04EDhXeclJxRWGwY/7xbm7k2zlEvWCKskoGAA3H3PkzUI +BSOKWoogqwXbRCfkuF6PfA== -----END PRIVATE KEY----- diff --git a/test/hostname/certindex b/test/hostname/certindex index 5b723c8534b7..28e4650a277e 100644 --- a/test/hostname/certindex +++ b/test/hostname/certindex @@ -6,3 +6,7 @@ V 21221008151638Z 32 unknown /CN=Alice/ST=California/C=US/emailAddress=do-not-r V 21221008151638Z 33 unknown /CN=Bob/ST=California/C=US/emailAddress=do-not-reply@hashicorp.com/O=End Point/OU=Testing V 21221008151638Z 34 unknown /CN=Betty/ST=California/C=US/emailAddress=do-not-reply@hashicorp.com/O=End Point/OU=Testing V 21221008151639Z 35 unknown /CN=Bonnie/ST=California/C=US/emailAddress=do-not-reply@hashicorp.com/O=End Point/OU=Testing +V 21231009141716Z 36 unknown /CN=Alice/ST=California/C=US/emailAddress=do-not-reply@hashicorp.com/O=End Point/OU=Testing +V 21231009141717Z 37 unknown /CN=Bob/ST=California/C=US/emailAddress=do-not-reply@hashicorp.com/O=End Point/OU=Testing +V 21231009141717Z 38 unknown /CN=Betty/ST=California/C=US/emailAddress=do-not-reply@hashicorp.com/O=End Point/OU=Testing +V 21231009141717Z 39 unknown /CN=Bonnie/ST=California/C=US/emailAddress=do-not-reply@hashicorp.com/O=End Point/OU=Testing diff --git a/test/hostname/serialfile b/test/hostname/serialfile index 7facc89938bb..44442d2d7b0b 100644 --- a/test/hostname/serialfile +++ b/test/hostname/serialfile @@ -1 +1 @@ -36 +3A diff --git a/test/integration/connect/envoy/helpers.bash b/test/integration/connect/envoy/helpers.bash index 01e59b6c2846..dad65089303f 100755 --- a/test/integration/connect/envoy/helpers.bash +++ b/test/integration/connect/envoy/helpers.bash @@ -328,6 +328,19 @@ function get_envoy_cluster_config { " } +function get_envoy_endpoints_configs { + local HOSTPORT=$1 + local CLUSTER_NAME=$2 + run retry_default curl -s -f $HOSTPORT/config_dump?include_eds=on + [ "$status" -eq 0 ] + echo "$output" | jq --raw-output " + .configs[] + | select(.\"@type\" == \"type.googleapis.com/envoy.admin.v3.EndpointsConfigDump\") + | .dynamic_endpoint_configs[] + | .endpoint_config + " +} + function get_envoy_stats_flush_interval { local HOSTPORT=$1 run retry_default curl -s -f $HOSTPORT/config_dump @@ -344,7 +357,7 @@ function snapshot_envoy_admin { local OUTDIR="${LOG_DIR}/envoy-snapshots/${DC}/${ENVOY_NAME}" mkdir -p "${OUTDIR}" - docker_wget "$DC" "http://${HOSTPORT}/config_dump" -q -O - >"${OUTDIR}/config_dump.json" + docker_wget "$DC" "http://${HOSTPORT}/config_dump?include_eds=on" -q -O - >"${OUTDIR}/config_dump.json" docker_wget "$DC" "http://${HOSTPORT}/clusters?format=json" -q -O - >"${OUTDIR}/clusters.json" docker_wget "$DC" "http://${HOSTPORT}/stats" -q -O - >"${OUTDIR}/stats.txt" docker_wget "$DC" "http://${HOSTPORT}/stats/prometheus" -q -O - >"${OUTDIR}/stats_prometheus.txt" diff --git a/test/integration/connect/envoy/helpers.windows.bash b/test/integration/connect/envoy/helpers.windows.bash index 5b6969ca8557..d8a1a0f5b875 100644 --- a/test/integration/connect/envoy/helpers.windows.bash +++ b/test/integration/connect/envoy/helpers.windows.bash @@ -389,7 +389,7 @@ function snapshot_envoy_admin { local OUTDIR="${LOG_DIR}/envoy-snapshots/${DC}/${ENVOY_NAME}" mkdir -p "${OUTDIR}" - docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/config_dump" > "${OUTDIR}/config_dump.json" + docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/config_dump?include_eds=on" > "${OUTDIR}/config_dump.json" docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/clusters?format=json" > "${OUTDIR}/clusters.json" docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/stats" > "${OUTDIR}/stats.txt" docker_consul_exec "$DC" bash -c "curl -s http://${HOSTPORT}/stats/prometheus" > "${OUTDIR}/stats_prometheus.txt" diff --git a/test/integration/connect/envoy/test-sds-server/go.mod b/test/integration/connect/envoy/test-sds-server/go.mod index 916d9b7211ac..48bc8283bbf2 100644 --- a/test/integration/connect/envoy/test-sds-server/go.mod +++ b/test/integration/connect/envoy/test-sds-server/go.mod @@ -3,13 +3,11 @@ module test-sds-server go 1.16 require ( - github.com/envoyproxy/go-control-plane v0.11.0 + github.com/envoyproxy/go-control-plane v0.11.1 github.com/fatih/color v1.14.1 // indirect github.com/hashicorp/consul v1.15.2 github.com/hashicorp/go-hclog v1.5.0 github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/stretchr/testify v1.8.3 // indirect - golang.org/x/net v0.13.0 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.55.0 + golang.org/x/net v0.17.0 // indirect + google.golang.org/grpc v1.56.3 ) diff --git a/test/integration/connect/envoy/test-sds-server/go.sum b/test/integration/connect/envoy/test-sds-server/go.sum index 1a851374f877..9a4f641fcfbb 100644 --- a/test/integration/connect/envoy/test-sds-server/go.sum +++ b/test/integration/connect/envoy/test-sds-server/go.sum @@ -172,6 +172,7 @@ cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvj cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA= cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU= +cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= @@ -751,8 +752,10 @@ github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195 h1:58f1tJ1ra+zFINPlwLWvQsR9CzAKt2e+EWV2yX9oXQ4= github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20230428030218-4003588d1b74/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/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/coredns/coredns v1.6.6/go.mod h1:Bdcnka9HmKGYj12ZIDF3lpQSfDHSsMc85Wj9xEyZUts= @@ -815,13 +818,17 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= -github.com/envoyproxy/go-control-plane v0.11.0 h1:jtLewhRR2vMRNnq2ZZUoCjUlgut+Y0+sDDWPOfwOi1o= github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= +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 v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w= -github.com/envoyproxy/protoc-gen-validate v0.10.0 h1:oIfnZFdC0YhpNNEX+SuIqko4cqqVZeN9IGTrhZje83Y= github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +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 v0.0.0-20190203023257-5858425f7550/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.1.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -1341,6 +1348,7 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2 github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o= +github.com/lyft/protoc-gen-star/v2 v2.0.3/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -1510,6 +1518,7 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: 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.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -1730,7 +1739,7 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1790,6 +1799,7 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180611182652-db08ff08e862/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1874,9 +1884,10 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +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-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1906,6 +1917,7 @@ golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec= golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= 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= @@ -2043,9 +2055,10 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/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-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2054,8 +2067,9 @@ golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2074,8 +2088,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/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-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2167,6 +2181,7 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/tools v0.8.0/go.mod h1:JxBZ99ISMI5ViVkT1tr6tdNmXeTrcpVSD3vZ1RsRdN4= 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= @@ -2384,8 +2399,18 @@ google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVix google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8= +google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e h1:AZX1ra8YbFMSb7+1pI8S9v4rrgRR7jU1FmuFSSjTVcQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e h1:NumxXLPfHSndr3wBBdeKiVHjGVFzi9RX2HwwQke94iY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -2430,10 +2455,12 @@ google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= +google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= 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= diff --git a/test/integration/consul-container/go.mod b/test/integration/consul-container/go.mod index 3bca51fc2193..8161503c518e 100644 --- a/test/integration/consul-container/go.mod +++ b/test/integration/consul-container/go.mod @@ -10,10 +10,10 @@ require ( github.com/evanphx/json-patch v4.12.0+incompatible github.com/go-jose/go-jose/v3 v3.0.0 github.com/hashicorp/consul v1.16.1 - github.com/hashicorp/consul/api v1.24.0 - github.com/hashicorp/consul/envoyextensions v0.4.1 - github.com/hashicorp/consul/proto-public v0.4.1 - github.com/hashicorp/consul/sdk v0.14.1 + github.com/hashicorp/consul/api v1.26.1 + github.com/hashicorp/consul/envoyextensions v0.5.1 + github.com/hashicorp/consul/proto-public v0.5.1 + github.com/hashicorp/consul/sdk v0.15.0 github.com/hashicorp/consul/testing/deployer v0.0.0-20230811171106-4a0afb5d1373 github.com/hashicorp/go-cleanhttp v0.5.2 github.com/hashicorp/go-multierror v1.1.1 @@ -30,8 +30,7 @@ require ( github.com/teris-io/shortid v0.0.0-20220617161101-71ec9f2aa569 github.com/testcontainers/testcontainers-go v0.22.0 golang.org/x/mod v0.12.0 - google.golang.org/grpc v1.57.0 - k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 + google.golang.org/grpc v1.57.2 ) require ( @@ -72,8 +71,8 @@ require ( 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-0.20230524094728-9239064ad72f // indirect - github.com/envoyproxy/protoc-gen-validate v0.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 @@ -105,6 +104,7 @@ require ( 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 @@ -113,6 +113,7 @@ require ( 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 @@ -132,7 +133,7 @@ require ( 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.3.0 // 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 @@ -176,7 +177,7 @@ require ( 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.3.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 @@ -199,14 +200,14 @@ require ( 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.12.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.14.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.11.0 // indirect - golang.org/x/term v0.11.0 // indirect - golang.org/x/text v0.12.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 @@ -225,6 +226,7 @@ require ( 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 diff --git a/test/integration/consul-container/go.sum b/test/integration/consul-container/go.sum index eeb6f251dd03..1cbb9315f5bc 100644 --- a/test/integration/consul-container/go.sum +++ b/test/integration/consul-container/go.sum @@ -178,11 +178,11 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f h1:7T++XKzy4xg7PKy+bM+Sa9/oe1OC88yz2hXQUISoXfA= -github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q= +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 v0.10.1 h1:c0g45+xCJhdgFGw7a5QAfdS4byAbud7miNWJ1WwEVf8= -github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +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= @@ -391,6 +391,8 @@ github.com/hashicorp/consul-awsauth v0.0.0-20220713182709-05ac1c5c2706 h1:1ZEjnv 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= @@ -425,6 +427,8 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-netaddrs v0.1.0 h1:TnlYvODD4C/wO+j7cX1z69kV5gOzI87u3OcUinANaW8= +github.com/hashicorp/go-netaddrs v0.1.0/go.mod h1:33+a/emi5R5dqRspOuZKO0E+Tuz5WV1F84eRWALkedA= github.com/hashicorp/go-plugin v1.4.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= @@ -492,8 +496,8 @@ github.com/hashicorp/raft-boltdb v0.0.0-20210409134258-03c10cc3d4ea/go.mod h1:qR 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.3.0 h1:Mi6RPoRbsxIIYZryI+bSTXHD97Ua6rIYO51ibYV9bkY= -github.com/hashicorp/raft-wal v0.3.0/go.mod h1:A6vP5o8hGOs1LHfC1Okh9xPwWDcmb6Vvuz/QyqUXlOE= +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= @@ -689,8 +693,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: 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.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +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= @@ -829,8 +833,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y 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.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +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= @@ -918,8 +922,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx 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.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +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= @@ -1025,13 +1029,13 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.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.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0= -golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +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= @@ -1043,8 +1047,8 @@ 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.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +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= @@ -1251,8 +1255,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K 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.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +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= diff --git a/test/integration/consul-container/libs/assert/envoy.go b/test/integration/consul-container/libs/assert/envoy.go index 760b1f87bc5a..076f2e1af62b 100644 --- a/test/integration/consul-container/libs/assert/envoy.go +++ b/test/integration/consul-container/libs/assert/envoy.go @@ -75,6 +75,7 @@ func GetEnvoyListenerTCPFiltersWithClient( // AssertUpstreamEndpointStatus validates that proxy was configured with provided clusterName in the healthStatus func AssertUpstreamEndpointStatus(t *testing.T, adminPort int, clusterName, healthStatus string, count int) { + t.Helper() require.True(t, adminPort > 0) AssertUpstreamEndpointStatusWithClient( t, @@ -94,6 +95,7 @@ func AssertUpstreamEndpointStatusWithClient( healthStatus string, count int, ) { + t.Helper() require.NotNil(t, client) require.NotEmpty(t, addr) failer := func() *retry.Timer { @@ -116,7 +118,7 @@ func AssertUpstreamEndpointStatusWithClient( clusterName, healthStatus) results, err := utils.JQFilter(clusters, filter) require.NoErrorf(r, err, "could not find cluster name %q: %v \n%s", clusterName, err, clusters) - require.Len(r, results, 1) // the final part of the pipeline is "length" which only ever returns 1 result + require.Len(r, results, 1, "clusters: "+clusters) // the final part of the pipeline is "length" which only ever returns 1 result result, err := strconv.Atoi(results[0]) assert.NoError(r, err) @@ -126,6 +128,7 @@ func AssertUpstreamEndpointStatusWithClient( // AssertEnvoyMetricAtMost assert the filered metric by prefix and metric is >= count func AssertEnvoyMetricAtMost(t *testing.T, adminPort int, prefix, metric string, count int) { + t.Helper() var ( stats string err error diff --git a/test/integration/consul-container/libs/assert/service.go b/test/integration/consul-container/libs/assert/service.go index 35fad6bfb15b..7434a1d5e36f 100644 --- a/test/integration/consul-container/libs/assert/service.go +++ b/test/integration/consul-container/libs/assert/service.go @@ -12,12 +12,16 @@ import ( "testing" "time" + "github.com/hashicorp/consul/api" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" + "github.com/hashicorp/consul/sdk/testutil" + "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/hashicorp/consul/testing/deployer/util" "github.com/hashicorp/go-cleanhttp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" libservice "github.com/hashicorp/consul/test/integration/consul-container/libs/service" ) @@ -26,6 +30,64 @@ const ( defaultHTTPWait = defaultWait ) +// CatalogV2ServiceExists verifies the service name exists in the Consul catalog +func CatalogV2ServiceExists(t *testing.T, client pbresource.ResourceServiceClient, svc string, tenancy *pbresource.Tenancy) { + t.Helper() + CatalogV2ServiceHasEndpointCount(t, client, svc, tenancy, -1) +} + +// CatalogV2ServiceDoesNotExist verifies the service name does not exist in the Consul catalog +func CatalogV2ServiceDoesNotExist(t *testing.T, client pbresource.ResourceServiceClient, svc string, tenancy *pbresource.Tenancy) { + t.Helper() + ctx := testutil.TestContext(t) + retry.Run(t, func(r *retry.R) { + got, err := util.GetDecodedResource[*pbcatalog.Service](ctx, client, &pbresource.ID{ + Type: pbcatalog.ServiceType, + Name: svc, + Tenancy: tenancy, + }) + require.NoError(r, err, "error reading service data") + require.Nil(r, got, "unexpectedly found Service resource for %q", svc) + + got2, err := util.GetDecodedResource[*pbcatalog.ServiceEndpoints](ctx, client, &pbresource.ID{ + Type: pbcatalog.ServiceEndpointsType, + Name: svc, + Tenancy: tenancy, + }) + require.NotNil(r, err, "error reading service data") + require.Nil(r, got2, "unexpectedly found ServiceEndpoints resource for %q", svc) + }) +} + +// CatalogV2ServiceHasEndpointCount verifies the service name exists in the Consul catalog and has the specified +// number of workload endpoints. +func CatalogV2ServiceHasEndpointCount(t *testing.T, client pbresource.ResourceServiceClient, svc string, tenancy *pbresource.Tenancy, count int) { + t.Helper() + + ctx := testutil.TestContext(t) + retry.Run(t, func(r *retry.R) { + got, err := util.GetDecodedResource[*pbcatalog.Service](ctx, client, &pbresource.ID{ + Type: pbcatalog.ServiceType, + Name: svc, + Tenancy: tenancy, + }) + require.NoError(r, err, "error reading service data") + require.NotNil(r, got, "did not find Service resource for %q", svc) + + got2, err := util.GetDecodedResource[*pbcatalog.ServiceEndpoints](ctx, client, &pbresource.ID{ + Type: pbcatalog.ServiceEndpointsType, + Name: svc, + Tenancy: tenancy, + }) + require.NoError(r, err, "error reading service data") + require.NotNil(r, got2, "did not find ServiceEndpoints resource for %q", svc) + require.NotEmpty(r, got2.Data.Endpoints, "did not find any workload data in the ServiceEndpoints resource for %q", svc) + if count > 0 { + require.Len(r, got2.Data.Endpoints, count) + } + }) +} + // CatalogServiceExists verifies the service name exists in the Consul catalog func CatalogServiceExists(t *testing.T, c *api.Client, svc string, opts *api.QueryOptions) { retry.Run(t, func(r *retry.R) { @@ -39,6 +101,15 @@ func CatalogServiceExists(t *testing.T, c *api.Client, svc string, opts *api.Que }) } +// CatalogServiceDoesNotExist verifies the service name does not exist in the Consul catalog +func CatalogServiceDoesNotExist(t *testing.T, c *api.Client, svc string, opts *api.QueryOptions) { + retry.Run(t, func(r *retry.R) { + services, _, err := c.Catalog().Service(svc, "", opts) + require.NoError(r, err, "error reading service data") + require.Empty(r, services) + }) +} + // CatalogServiceHasInstanceCount verifies the service name exists in the Consul catalog and has the specified // number of instances. func CatalogServiceHasInstanceCount(t *testing.T, c *api.Client, svc string, count int, opts *api.QueryOptions) { @@ -66,6 +137,17 @@ func CatalogNodeExists(t *testing.T, c *api.Client, nodeName string) { }) } +// CatalogNodeDoesNotExist verifies the node name does not exist in the Consul catalog +func CatalogNodeDoesNotExist(t *testing.T, c *api.Client, nodeName string) { + retry.Run(t, func(r *retry.R) { + node, _, err := c.Catalog().Node(nodeName, nil) + if err != nil { + r.Fatal("error reading node data") + } + require.Nil(r, node) + }) +} + // CatalogServiceIsHealthy verifies the service name exists and all instances pass healthchecks func CatalogServiceIsHealthy(t *testing.T, c *api.Client, svc string, opts *api.QueryOptions) { CatalogServiceExists(t, c, svc, opts) @@ -105,6 +187,7 @@ func HTTPServiceEchoesWithClient(t *testing.T, client *http.Client, addr string, func HTTPServiceEchoesResHeader(t *testing.T, ip string, port int, path string, expectedResHeader map[string]string) { doHTTPServiceEchoes(t, ip, port, path, nil, expectedResHeader) } + func HTTPServiceEchoesResHeaderWithClient(t *testing.T, client *http.Client, addr string, path string, expectedResHeader map[string]string) { doHTTPServiceEchoesWithClient(t, client, addr, path, nil, expectedResHeader) } @@ -142,7 +225,7 @@ func doHTTPServiceEchoesWithClient( reader := strings.NewReader(phrase) req, err := http.NewRequest("POST", url, reader) - require.NoError(t, err, "could not construct request") + require.NoError(r, err, "could not construct request") for k, v := range requestHeaders { req.Header.Add(k, v) diff --git a/test/integration/consul-container/libs/cluster/agent.go b/test/integration/consul-container/libs/cluster/agent.go index 09568f21c565..a6dcb546749e 100644 --- a/test/integration/consul-container/libs/cluster/agent.go +++ b/test/integration/consul-container/libs/cluster/agent.go @@ -10,7 +10,6 @@ import ( "io" jsonpatch "github.com/evanphx/json-patch" - agentconfig "github.com/hashicorp/consul/agent/config" "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/lib/decode" "github.com/hashicorp/hcl" @@ -96,10 +95,6 @@ func (c Config) Clone() Config { return c2 } -type decodeTarget struct { - agentconfig.Config `mapstructure:",squash"` -} - // MutatebyAgentConfig mutates config by applying the fields in the input hclConfig // Note that the precedence order is config > hclConfig, because user provider hclConfig // may not work with the testing environment, e.g., data dir, agent name, etc. @@ -135,7 +130,10 @@ func convertHcl2Json(in string) (string, error) { return "", err } - var target decodeTarget + // We target an opaque map so that changes to config fields not yet present + // in a tagged version of `consul` (missing from latest released schema) + // can be used in tests. + var target map[string]any var md mapstructure.Metadata d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{ DecodeHook: mapstructure.ComposeDecodeHookFunc( diff --git a/test/integration/consul-container/libs/cluster/cluster.go b/test/integration/consul-container/libs/cluster/cluster.go index fbee48333eb1..630fda2bc4a3 100644 --- a/test/integration/consul-container/libs/cluster/cluster.go +++ b/test/integration/consul-container/libs/cluster/cluster.go @@ -16,13 +16,13 @@ import ( "time" goretry "github.com/avast/retry-go" - "github.com/hashicorp/consul/api" - "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/serf/serf" "github.com/stretchr/testify/require" "github.com/teris-io/shortid" "github.com/testcontainers/testcontainers-go" + "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/sdk/testutil/retry" "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) diff --git a/test/integration/consul-container/libs/utils/version.go b/test/integration/consul-container/libs/utils/version.go index 24e66a869814..1f62306f4479 100644 --- a/test/integration/consul-container/libs/utils/version.go +++ b/test/integration/consul-container/libs/utils/version.go @@ -5,6 +5,7 @@ package utils import ( "flag" + "os" "strings" "github.com/hashicorp/consul/testing/deployer/topology" @@ -59,15 +60,18 @@ func GetLatestImageName() string { func TargetImages() topology.Images { img := DockerImage(targetImageName, TargetVersion) + var set topology.Images if IsEnterprise() { - return topology.Images{ - ConsulEnterprise: img, - } + set.ConsulEnterprise = img } else { - return topology.Images{ - ConsulCE: img, - } + set.ConsulCE = img } + + if cdp := os.Getenv("DEPLOYER_CONSUL_DATAPLANE_IMAGE"); cdp != "" { + set.Dataplane = cdp + } + + return set } func IsEnterprise() bool { return isInEnterpriseRepo } diff --git a/test/integration/consul-container/test/gateways/http_route_test.go b/test/integration/consul-container/test/gateways/http_route_test.go index 96c93da955a4..bf2c7d69567e 100644 --- a/test/integration/consul-container/test/gateways/http_route_test.go +++ b/test/integration/consul-container/test/gateways/http_route_test.go @@ -9,7 +9,6 @@ import ( "encoding/hex" "fmt" "github.com/testcontainers/testcontainers-go" - "k8s.io/utils/pointer" "testing" "time" @@ -869,7 +868,7 @@ func TestHTTPRouteRetryAndTimeout(t *testing.T) { { Filters: api.HTTPFilters{ RetryFilter: &api.RetryFilter{ - NumRetries: pointer.Uint32(10), + NumRetries: 10, RetryOnStatusCodes: []uint32{500}, }, }, diff --git a/test/integration/consul-container/test/ratelimit/ratelimit_test.go b/test/integration/consul-container/test/ratelimit/ratelimit_test.go index e598e0ceb8ad..89293da7f8ee 100644 --- a/test/integration/consul-container/test/ratelimit/ratelimit_test.go +++ b/test/integration/consul-container/test/ratelimit/ratelimit_test.go @@ -4,17 +4,19 @@ package ratelimit import ( + "context" "fmt" "strings" "testing" "time" - "github.com/stretchr/testify/require" - "github.com/hashicorp/consul/api" "github.com/hashicorp/consul/sdk/testutil/retry" + "github.com/stretchr/testify/require" + libcluster "github.com/hashicorp/consul/test/integration/consul-container/libs/cluster" libtopology "github.com/hashicorp/consul/test/integration/consul-container/libs/topology" + "github.com/hashicorp/consul/test/integration/consul-container/libs/utils" ) const ( @@ -45,10 +47,11 @@ func TestServerRequestRateLimit(t *testing.T) { expectMetric bool } type testCase struct { - description string - cmd string - operations []operation - mode string + description string + cmd string + operations []operation + mode string + enterpriseOnly bool } // getKV and putKV are net/RPC calls @@ -69,6 +72,30 @@ func TestServerRequestRateLimit(t *testing.T) { rateLimitType: "global/write", } + // listPartition and putPartition are gRPC calls + listPartition := action{ + function: func(client *api.Client) error { + ctx := context.Background() + _, _, err := client.Partitions().List(ctx, nil) + return err + }, + rateLimitOperation: "/partition.PartitionService/List", + rateLimitType: "global/read", + } + + putPartition := action{ + function: func(client *api.Client) error { + ctx := context.Background() + p := api.Partition{ + Name: "ptest", + } + _, _, err := client.Partitions().Create(ctx, &p, nil) + return err + }, + rateLimitOperation: "/partition.PartitionService/Write", + rateLimitType: "global/write", + } + testCases := []testCase{ // HTTP & net/RPC { @@ -128,9 +155,73 @@ func TestServerRequestRateLimit(t *testing.T) { }, }, }, + // gRPC + { + description: "GRPC / Mode: disabled - errors: no / exceeded logs: no / metrics: no", + cmd: `-hcl=limits { request_limits { mode = "disabled" read_rate = 0 write_rate = 0 }}`, + mode: "disabled", + operations: []operation{ + { + action: putPartition, + expectedErrorMsg: "", + expectExceededLog: false, + expectMetric: false, + }, + { + action: listPartition, + expectedErrorMsg: "", + expectExceededLog: false, + expectMetric: false, + }, + }, + enterpriseOnly: true, + }, + { + description: "GRPC / Mode: permissive - errors: no / exceeded logs: yes / metrics: no", + cmd: `-hcl=limits { request_limits { mode = "permissive" read_rate = 0 write_rate = 0 }}`, + mode: "permissive", + operations: []operation{ + { + action: putPartition, + expectedErrorMsg: "", + expectExceededLog: true, + expectMetric: true, + }, + { + action: listPartition, + expectedErrorMsg: "", + expectExceededLog: true, + expectMetric: true, + }, + }, + enterpriseOnly: true, + }, + { + description: "GRPC / Mode: enforcing - errors: yes / exceeded logs: yes / metrics: yes", + cmd: `-hcl=limits { request_limits { mode = "enforcing" read_rate = 0 write_rate = 0 }}`, + mode: "enforcing", + operations: []operation{ + { + action: putPartition, + expectedErrorMsg: nonRetryableErrorMsg, + expectExceededLog: true, + expectMetric: true, + }, + { + action: listPartition, + expectedErrorMsg: retryableErrorMsg, + expectExceededLog: true, + expectMetric: true, + }, + }, + enterpriseOnly: true, + }, } for _, tc := range testCases { + if tc.enterpriseOnly && !utils.IsEnterprise() { + continue + } tc := tc t.Run(tc.description, func(t *testing.T) { t.Parallel() diff --git a/testing/deployer/go.mod b/testing/deployer/go.mod index df6cb924f087..9a8f53a322ac 100644 --- a/testing/deployer/go.mod +++ b/testing/deployer/go.mod @@ -4,44 +4,64 @@ 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.24.0 - github.com/hashicorp/consul/sdk v0.14.1 + 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 github.com/hashicorp/go-multierror v1.1.1 + github.com/hashicorp/go-rootcerts v1.0.2 github.com/hashicorp/hcl/v2 v2.16.2 github.com/mitchellh/copystructure v1.2.0 github.com/rboyer/safeio v0.2.2 github.com/stretchr/testify v1.8.3 - golang.org/x/crypto v0.11.0 + golang.org/x/crypto v0.14.0 + golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 + google.golang.org/grpc v1.56.3 + google.golang.org/protobuf v1.31.0 ) require ( github.com/agext/levenshtein v1.2.1 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/fatih/color v1.14.1 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect - github.com/hashicorp/go-rootcerts v1.0.2 // indirect + github.com/hashicorp/go-netaddrs v0.1.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/serf v0.10.1 // 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.1 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus/client_golang v1.11.1 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.26.0 // indirect + github.com/prometheus/procfs v0.6.0 // indirect github.com/zclconf/go-cty v1.12.1 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/sys v0.10.0 // indirect - golang.org/x/text v0.11.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) -replace github.com/hashicorp/consul/sdk => ../../sdk +replace ( + github.com/hashicorp/consul/api => ../../api + github.com/hashicorp/consul/proto-public => ../../proto-public + github.com/hashicorp/consul/sdk => ../../sdk +) diff --git a/testing/deployer/go.sum b/testing/deployer/go.sum index fb90eb4a6a33..e632e8be7907 100644 --- a/testing/deployer/go.sum +++ b/testing/deployer/go.sum @@ -1,3 +1,4 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= @@ -5,6 +6,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy 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/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 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/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -15,9 +17,14 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 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/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= 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/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -31,23 +38,38 @@ github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= 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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 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.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.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.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +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.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.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/hashicorp/consul/api v1.24.0 h1:u2XyStA2j0jnCiVUU7Qyrt8idjRn4ORhK6DlvZ3bWhA= -github.com/hashicorp/consul/api v1.24.0/go.mod h1:NZJGRFYruc/80wYowkPFCp1LbGmJC9L8izrwfyVx/Wg= +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= @@ -65,6 +87,8 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-netaddrs v0.1.0 h1:TnlYvODD4C/wO+j7cX1z69kV5gOzI87u3OcUinANaW8= +github.com/hashicorp/go-netaddrs v0.1.0/go.mod h1:33+a/emi5R5dqRspOuZKO0E+Tuz5WV1F84eRWALkedA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= @@ -88,10 +112,15 @@ github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= 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.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/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.3/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.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= @@ -114,6 +143,7 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= @@ -135,6 +165,7 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ 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/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/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= @@ -150,14 +181,24 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 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.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= 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.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 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.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/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.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rboyer/safeio v0.2.2 h1:XhtqyUTRleMYGyBt3ni4j2BtEh669U2ry2INnnd+B4k= github.com/rboyer/safeio v0.2.2/go.mod h1:pSnr2LFXyn/c/fotxotyOdYy7pP/XSh6MpBmzXPjiNc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -167,6 +208,7 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg 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.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 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.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= @@ -182,56 +224,85 @@ github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeW 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-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +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-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ= +golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/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-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 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-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= +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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 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-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-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/sys v0.0.0-20180823144017-11551d06cbcc/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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/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-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-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-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.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= -golang.org/x/sys v0.10.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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= +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.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +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.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-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -240,5 +311,6 @@ 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.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.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/testing/deployer/sprawl/acl_rules.go b/testing/deployer/sprawl/acl_rules.go index 7c360d85f610..98910126b303 100644 --- a/testing/deployer/sprawl/acl_rules.go +++ b/testing/deployer/sprawl/acl_rules.go @@ -93,6 +93,13 @@ func tokenForService(svc *topology.Service, overridePolicy *api.ACLPolicy, enter } if overridePolicy != nil { token.Policies = []*api.ACLTokenPolicyLink{{ID: overridePolicy.ID}} + } else if svc.IsV2() { + token.TemplatedPolicies = []*api.ACLTemplatedPolicy{{ + TemplateName: api.ACLTemplatedPolicyWorkloadIdentityName, + TemplateVariables: &api.ACLTemplatedPolicyVariables{ + Name: svc.ID.Name, + }, + }} } else { token.ServiceIdentities = []*api.ACLServiceIdentity{{ ServiceName: svc.ID.Name, diff --git a/testing/deployer/sprawl/boot.go b/testing/deployer/sprawl/boot.go index 89c887c7574e..3bbb9e864e87 100644 --- a/testing/deployer/sprawl/boot.go +++ b/testing/deployer/sprawl/boot.go @@ -32,9 +32,11 @@ const ( func (s *Sprawl) launch() error { return s.launchType(true) } + func (s *Sprawl) relaunch() error { return s.launchType(false) } + func (s *Sprawl) launchType(firstTime bool) (launchErr error) { if err := build.DockerImages(s.logger, s.runner, s.topology); err != nil { return fmt.Errorf("build.DockerImages: %w", err) @@ -180,6 +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) } } } @@ -234,6 +237,14 @@ func (s *Sprawl) initConsulServers() error { return fmt.Errorf("error creating final client for cluster=%s: %v", cluster.Name, err) } + // Connect to gRPC as well. + if cluster.EnableV2 { + s.grpcConns[cluster.Name], s.grpcConnCancel[cluster.Name], err = s.dialServerGRPC(cluster, node, mgmtToken) + if err != nil { + return fmt.Errorf("error creating gRPC client conn for cluster=%s: %w", cluster.Name, err) + } + } + // For some reason the grpc resolver stuff for partitions takes some // time to get ready. s.waitForLocalWrites(cluster, mgmtToken) @@ -249,6 +260,10 @@ 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 err := s.createAnonymousToken(cluster); err != nil { return fmt.Errorf("createAnonymousToken[%s]: %w", cluster.Name, err) } @@ -456,6 +471,9 @@ func (s *Sprawl) waitForLocalWrites(cluster *topology.Cluster, token string) { } func (s *Sprawl) waitForClientAntiEntropyOnce(cluster *topology.Cluster) error { + if cluster.EnableV2 { + return nil // v1 catalog is disabled when v2 catalog is enabled + } var ( client = s.clients[cluster.Name] logger = s.logger.With("cluster", cluster.Name) @@ -504,7 +522,7 @@ func (s *Sprawl) waitForClientAntiEntropyOnce(cluster *topology.Cluster) error { logger.Debug("all nodes have posted node updates, so first anti-entropy has happened", "elapsed", dur) return nil } - logger.Debug("not all client nodes have posted node updates yet", "nodes", stragglers) + logger.Debug("not all nodes have posted node updates yet", "nodes", stragglers) time.Sleep(1 * time.Second) } @@ -514,10 +532,10 @@ func newGossipKey() (string, error) { key := make([]byte, 16) n, err := rand.Reader.Read(key) if err != nil { - return "", fmt.Errorf("Error reading random data: %s", err) + return "", fmt.Errorf("error reading random data: %s", err) } if n != 16 { - return "", fmt.Errorf("Couldn't read enough entropy. Generate more entropy!") + return "", fmt.Errorf("couldn't read enough entropy. Generate more entropy") } return base64.StdEncoding.EncodeToString(key), nil } diff --git a/testing/deployer/sprawl/catalog.go b/testing/deployer/sprawl/catalog.go index fc5d2dbc399d..fdc95c9f6893 100644 --- a/testing/deployer/sprawl/catalog.go +++ b/testing/deployer/sprawl/catalog.go @@ -4,11 +4,18 @@ package sprawl import ( + "context" "fmt" "net/http" "time" "github.com/hashicorp/consul/api" + pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/consul/testing/deployer/topology" "github.com/hashicorp/consul/testing/deployer/util" @@ -41,6 +48,9 @@ func (s *Sprawl) registerServicesToAgents(cluster *topology.Cluster) error { if !node.IsAgent() { continue } + if node.IsV2() { + panic("don't call this") + } agentClient, err := util.ProxyAPIClient( node.LocalProxyPort(), @@ -71,6 +81,9 @@ func (s *Sprawl) registerAgentService( if !node.IsAgent() { panic("called wrong method type") } + if node.IsV2() { + panic("don't call this") + } if svc.IsMeshGateway { return nil // handled at startup time for agent-full, but won't be for agent-less @@ -164,6 +177,8 @@ RETRY: } func (s *Sprawl) registerServicesForDataplaneInstances(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 @@ -178,13 +193,98 @@ func (s *Sprawl) registerServicesForDataplaneInstances(cluster *topology.Cluster } for _, svc := range node.Services { - if err := s.registerCatalogService(cluster, node, svc); err != nil { - return fmt.Errorf("error registering service: %w", err) - } - if !svc.DisableServiceMesh { - if err := s.registerCatalogSidecarService(cluster, node, svc); err != nil { - return fmt.Errorf("error registering sidecar service: %w", err) + 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 + } + + // 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(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) + } + 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 + } + } + } 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) + } + } + } + } + } + + 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 + } + } + + if cluster.EnableV2 { + for id, svcData := range cluster.Services { + svcInfo := &Resource[*pbcatalog.Service]{ + Resource: &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbcatalog.ServiceType, + Name: id.Name, + Tenancy: &pbresource.Tenancy{ + Partition: id.Partition, + Namespace: id.Namespace, + }, + }, + }, + Data: svcData, + } + + res, err := svcInfo.Build() + if err != nil { + return fmt.Errorf("error serializing resource %s: %w", util.IDToString(svcInfo.Resource.Id), err) + } + if _, err := s.writeResource(cluster, res); err != nil { + return err } } } @@ -195,6 +295,86 @@ func (s *Sprawl) registerServicesForDataplaneInstances(cluster *topology.Cluster func (s *Sprawl) registerCatalogNode( cluster *topology.Cluster, node *topology.Node, +) error { + if node.IsV2() { + + // TODO(rb): nodes are optional in v2 and won't be used in k8s by + // default. There are some scoping issues with the Node Type in 1.17 so + // disable it for now. + // + // To re-enable you also need to link it to the Workload by setting the + // NodeName field. + // + // return s.registerCatalogNodeV2(cluster, node) + return nil + } + return s.registerCatalogNodeV1(cluster, node) +} + +func (s *Sprawl) registerCatalogNodeV2( + cluster *topology.Cluster, + node *topology.Node, +) error { + if !node.IsDataplane() { + panic("called wrong method type") + } + + nodeRes := &Resource[*pbcatalog.Node]{ + Resource: &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbcatalog.NodeType, + Name: node.PodName(), + Tenancy: &pbresource.Tenancy{ + Partition: node.Partition, + Namespace: "default", // temporary requirement + }, + }, + Metadata: map[string]string{ + "dataplane-faux": "1", + }, + }, + Data: &pbcatalog.Node{ + Addresses: []*pbcatalog.NodeAddress{ + {Host: node.LocalAddress()}, + }, + }, + } + + res, err := nodeRes.Build() + if err != nil { + return err + } + + _, err = s.writeResource(cluster, res) + return err +} + +func (s *Sprawl) writeResource(cluster *topology.Cluster, res *pbresource.Resource) (*pbresource.Resource, error) { + var ( + client = s.getResourceClient(cluster.Name) + logger = s.logger.With("cluster", cluster.Name) + ) + + ctx := s.getManagementTokenContext(context.Background(), cluster.Name) +RETRY: + wrote, err := client.Write(ctx, &pbresource.WriteRequest{ + Resource: res, + }) + if err != nil { + if isACLNotFound(err) { // TODO: is this right for v2? + time.Sleep(50 * time.Millisecond) + goto RETRY + } + return nil, fmt.Errorf("error creating resource %s: %w", util.IDToString(res.Id), err) + } + + logger.Info("resource upserted", "id", util.IDToString(res.Id)) + return wrote.Resource, nil +} + +func (s *Sprawl) registerCatalogNodeV1( + cluster *topology.Cluster, + node *topology.Node, ) error { if !node.IsDataplane() { panic("called wrong method type") @@ -233,7 +413,7 @@ RETRY: return nil } -func (s *Sprawl) registerCatalogService( +func (s *Sprawl) registerCatalogServiceV1( cluster *topology.Cluster, node *topology.Node, svc *topology.Service, @@ -241,6 +421,9 @@ func (s *Sprawl) registerCatalogService( if !node.IsDataplane() { panic("called wrong method type") } + if node.IsV2() { + panic("don't call this") + } var ( client = s.clients[cluster.Name] @@ -266,7 +449,7 @@ RETRY: return nil } -func (s *Sprawl) registerCatalogSidecarService( +func (s *Sprawl) registerCatalogSidecarServiceV1( cluster *topology.Cluster, node *topology.Node, svc *topology.Service, @@ -277,6 +460,9 @@ func (s *Sprawl) registerCatalogSidecarService( if svc.DisableServiceMesh { panic("not valid") } + if node.IsV2() { + panic("don't call this") + } var ( client = s.clients[cluster.Name] @@ -301,11 +487,187 @@ RETRY: return nil } +type Resource[V proto.Message] struct { + Resource *pbresource.Resource + Data V +} + +func (r *Resource[V]) Build() (*pbresource.Resource, error) { + anyData, err := anypb.New(r.Data) + if err != nil { + return nil, err + } + r.Resource.Data = anyData + return r.Resource, nil +} + +type ServiceResources struct { + Workload *Resource[*pbcatalog.Workload] + HealthStatuses []*Resource[*pbcatalog.HealthStatus] + Destinations *Resource[*pbmesh.Destinations] + WorkloadIdentity *Resource[*pbauth.WorkloadIdentity] + ProxyConfiguration *Resource[*pbmesh.ProxyConfiguration] +} + +func serviceInstanceToResources( + node *topology.Node, + svc *topology.Service, +) *ServiceResources { + if svc.IsMeshGateway { + panic("v2 does not yet support mesh gateways") + } + + tenancy := &pbresource.Tenancy{ + Partition: svc.ID.Partition, + Namespace: svc.ID.Namespace, + } + + var ( + wlPorts = map[string]*pbcatalog.WorkloadPort{} + ) + for name, port := range svc.Ports { + wlPorts[name] = &pbcatalog.WorkloadPort{ + Port: uint32(port.Number), + Protocol: port.ActualProtocol, + } + } + + var ( + selector = &pbcatalog.WorkloadSelector{ + Names: []string{svc.Workload}, + } + + workloadRes = &Resource[*pbcatalog.Workload]{ + Resource: &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbcatalog.WorkloadType, + Name: svc.Workload, + Tenancy: tenancy, + }, + Metadata: svc.Meta, + }, + Data: &pbcatalog.Workload{ + // TODO(rb): disabling this until node scoping makes sense again + // NodeName: node.PodName(), + Identity: svc.ID.Name, + Ports: wlPorts, + Addresses: []*pbcatalog.WorkloadAddress{ + {Host: node.LocalAddress()}, + }, + }, + } + workloadIdentityRes = &Resource[*pbauth.WorkloadIdentity]{ + Resource: &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbauth.WorkloadIdentityType, + Name: svc.WorkloadIdentity, + Tenancy: tenancy, + }, + }, + Data: &pbauth.WorkloadIdentity{}, + } + + healthResList []*Resource[*pbcatalog.HealthStatus] + destinationsRes *Resource[*pbmesh.Destinations] + proxyConfigRes *Resource[*pbmesh.ProxyConfiguration] + ) + + if svc.HasCheck() { + // TODO: needs ownerId + checkRes := &Resource[*pbcatalog.HealthStatus]{ + Resource: &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbcatalog.HealthStatusType, + Name: svc.Workload + "-check-0", + Tenancy: tenancy, + }, + }, + Data: &pbcatalog.HealthStatus{ + Type: "external-sync", + Status: pbcatalog.Health_HEALTH_PASSING, + }, + } + + healthResList = []*Resource[*pbcatalog.HealthStatus]{checkRes} + } + + if node.HasPublicAddress() { + workloadRes.Data.Addresses = append(workloadRes.Data.Addresses, + &pbcatalog.WorkloadAddress{Host: node.PublicAddress(), External: true}, + ) + } + + if !svc.DisableServiceMesh { + destinationsRes = &Resource[*pbmesh.Destinations]{ + Resource: &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbmesh.DestinationsType, + Name: svc.Workload, + Tenancy: tenancy, + }, + }, + Data: &pbmesh.Destinations{ + Workloads: selector, + }, + } + + for _, u := range svc.Upstreams { + dest := &pbmesh.Destination{ + DestinationRef: &pbresource.Reference{ + Type: pbcatalog.ServiceType, + Name: u.ID.Name, + Tenancy: &pbresource.Tenancy{ + Partition: u.ID.Partition, + Namespace: u.ID.Namespace, + }, + }, + DestinationPort: u.PortName, + ListenAddr: &pbmesh.Destination_IpPort{ + IpPort: &pbmesh.IPPortAddress{ + Ip: u.LocalAddress, + Port: uint32(u.LocalPort), + }, + }, + } + destinationsRes.Data.Destinations = append(destinationsRes.Data.Destinations, dest) + } + + if svc.EnableTransparentProxy { + proxyConfigRes = &Resource[*pbmesh.ProxyConfiguration]{ + Resource: &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbmesh.ProxyConfigurationType, + Name: svc.Workload, + Tenancy: tenancy, + }, + }, + Data: &pbmesh.ProxyConfiguration{ + Workloads: selector, + DynamicConfig: &pbmesh.DynamicConfig{ + Mode: pbmesh.ProxyMode_PROXY_MODE_TRANSPARENT, + }, + }, + } + } + } + + return &ServiceResources{ + Workload: workloadRes, + HealthStatuses: healthResList, + Destinations: destinationsRes, + WorkloadIdentity: workloadIdentityRes, + ProxyConfiguration: proxyConfigRes, + } +} + func serviceToCatalogRegistration( cluster *topology.Cluster, node *topology.Node, svc *topology.Service, ) *api.CatalogRegistration { + if node.IsV2() { + panic("don't call this") + } reg := &api.CatalogRegistration{ Node: node.PodName(), SkipNodeUpdate: true, @@ -394,6 +756,9 @@ func serviceToSidecarCatalogRegistration( node *topology.Node, svc *topology.Service, ) (topology.ServiceID, *api.CatalogRegistration) { + if node.IsV2() { + panic("don't call this") + } pid := svc.ID pid.Name += "-sidecar-proxy" reg := &api.CatalogRegistration{ diff --git a/testing/deployer/sprawl/consul.go b/testing/deployer/sprawl/consul.go index 269313578415..205fb0235f0e 100644 --- a/testing/deployer/sprawl/consul.go +++ b/testing/deployer/sprawl/consul.go @@ -4,17 +4,29 @@ package sprawl import ( + "context" "errors" "fmt" "time" "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" "github.com/hashicorp/consul/testing/deployer/topology" "github.com/hashicorp/consul/testing/deployer/util" ) +func (s *Sprawl) getResourceClient(clusterName string) pbresource.ResourceServiceClient { + return pbresource.NewResourceServiceClient(s.grpcConns[clusterName]) +} + +func (s *Sprawl) getManagementTokenContext(ctx context.Context, clusterName string) context.Context { + mgmtToken := s.secrets.ReadGeneric(clusterName, secrets.BootstrapToken) + //nolint:staticcheck + return context.WithValue(ctx, "x-consul-token", mgmtToken) +} + func getLeader(client *api.Client) (string, error) { leaderAdd, err := client.Status().Leader() if err != nil { diff --git a/testing/deployer/sprawl/details.go b/testing/deployer/sprawl/details.go index c463d310d873..a0c6c0c2a51e 100644 --- a/testing/deployer/sprawl/details.go +++ b/testing/deployer/sprawl/details.go @@ -70,10 +70,15 @@ func (s *Sprawl) PrintDetails() error { Service: svc.ID.String(), }) } else { + ports := make(map[string]int) + for name, port := range svc.Ports { + ports[name] = node.ExposedPort(port.Number) + } cd.Apps = append(cd.Apps, appDetail{ Type: "app", Container: node.DockerName(), ExposedPort: node.ExposedPort(svc.Port), + ExposedPorts: ports, ExposedEnvoyAdminPort: node.ExposedPort(svc.EnvoyAdminPort), Addresses: addrs, Service: svc.ID.String(), @@ -115,19 +120,23 @@ func (s *Sprawl) PrintDetails() error { return false } - if a.Service < b.Service { - return true - } else if a.Service > b.Service { - return false - } - - return a.ExposedPort < b.ExposedPort + return a.Service < b.Service }) for _, d := range cluster.Apps { if d.Type == "server" && d.Container == cluster.Leader { d.Type = "leader" } - portStr := "app=" + strconv.Itoa(d.ExposedPort) + var portStr string + if len(d.ExposedPorts) > 0 { + var out []string + for name, exposed := range d.ExposedPorts { + out = append(out, fmt.Sprintf("app:%s=%d", name, exposed)) + } + sort.Strings(out) + portStr = strings.Join(out, " ") + } else { + portStr = "app=" + strconv.Itoa(d.ExposedPort) + } if d.ExposedEnvoyAdminPort > 0 { portStr += " envoy=" + strconv.Itoa(d.ExposedEnvoyAdminPort) } @@ -166,8 +175,9 @@ type appDetail struct { Type string // server|mesh-gateway|app Container string Addresses []string - ExposedPort int `json:",omitempty"` - ExposedEnvoyAdminPort int `json:",omitempty"` + ExposedPort int `json:",omitempty"` + ExposedPorts map[string]int `json:",omitempty"` + ExposedEnvoyAdminPort int `json:",omitempty"` // just services Service string `json:",omitempty"` } diff --git a/testing/deployer/sprawl/grpc.go b/testing/deployer/sprawl/grpc.go new file mode 100644 index 000000000000..fc4927bb32c8 --- /dev/null +++ b/testing/deployer/sprawl/grpc.go @@ -0,0 +1,42 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package sprawl + +import ( + "context" + "crypto/tls" + "fmt" + + "github.com/hashicorp/go-rootcerts" + "google.golang.org/grpc" + + "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" + "github.com/hashicorp/consul/testing/deployer/topology" + "github.com/hashicorp/consul/testing/deployer/util" +) + +func (s *Sprawl) dialServerGRPC(cluster *topology.Cluster, node *topology.Node, token string) (*grpc.ClientConn, func(), error) { + var ( + logger = s.logger.With("cluster", cluster.Name) + ) + + tls := &tls.Config{ + ServerName: fmt.Sprintf("server.%s.consul", cluster.Datacenter), + } + + rootConfig := &rootcerts.Config{ + CACertificate: []byte(s.secrets.ReadGeneric(cluster.Name, secrets.CAPEM)), + } + if err := rootcerts.ConfigureTLS(tls, rootConfig); err != nil { + return nil, nil, err + } + + return util.DialExposedGRPCConn( + context.Background(), + logger, + node.ExposedPort(8503), + token, + tls, + ) +} diff --git a/testing/deployer/sprawl/internal/build/docker.go b/testing/deployer/sprawl/internal/build/docker.go index ac1976dad4ee..435fb0b50648 100644 --- a/testing/deployer/sprawl/internal/build/docker.go +++ b/testing/deployer/sprawl/internal/build/docker.go @@ -35,28 +35,89 @@ USER 100:0 ENTRYPOINT [] ` +const dockerfileDataplaneForTProxy = ` +ARG DATAPLANE_IMAGE +ARG CONSUL_IMAGE +FROM ${CONSUL_IMAGE} AS consul +FROM ${DATAPLANE_IMAGE} AS distroless +FROM debian:bullseye-slim + +# undo the distroless aspect +COPY --from=distroless /usr/local/bin/discover /usr/local/bin/ +COPY --from=distroless /usr/local/bin/envoy /usr/local/bin/ +COPY --from=distroless /usr/local/bin/consul-dataplane /usr/local/bin/ +COPY --from=distroless /licenses/copyright.txt /licenses/ + +COPY --from=consul /bin/consul /bin/ + +# Install iptables and sudo, needed for tproxy. +RUN apt update -y \ + && apt install -y iptables sudo curl dnsutils + +RUN sed '/_apt/d' /etc/passwd > /etc/passwd.new \ + && mv -f /etc/passwd.new /etc/passwd \ + && adduser --uid=100 consul --no-create-home --disabled-password --system \ + && adduser consul sudo \ + && echo 'consul ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +COPY <<'EOF' /bin/tproxy-startup.sh +#!/bin/sh + +set -ex + +# HACK: UID of consul in the consul-client container +# This is conveniently also the UID of apt in the envoy container +CONSUL_UID=100 +ENVOY_UID=$(id -u) + +# - We allow 19000 so that the test can directly visit the envoy admin page. +# - We allow 20000 so that envoy can receive mTLS traffic from other nodes. +# - We (reluctantly) allow 8080 so that we can bypass envoy and talk to fortio +# to do test assertions. +sudo consul connect redirect-traffic \ + -proxy-uid $ENVOY_UID \ + -exclude-uid $CONSUL_UID \ + -proxy-inbound-port=15001 \ + -exclude-inbound-port=19000 \ + -exclude-inbound-port=20000 \ + -exclude-inbound-port=8080 +exec "$@" +EOF + +RUN chmod +x /bin/tproxy-startup.sh \ + && chown 100:0 /bin/tproxy-startup.sh + +RUN echo 'consul ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers + +USER 100:0 +ENTRYPOINT [] +` + func DockerImages( logger hclog.Logger, run *runner.Runner, t *topology.Topology, ) error { - logw := logger.Named("docker").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug}) built := make(map[string]struct{}) for _, c := range t.Clusters { for _, n := range c.Nodes { joint := n.Images.EnvoyConsulImage() if _, ok := built[joint]; joint != "" && !ok { - logger.Info("building image", "image", joint) - err := run.DockerExec(context.TODO(), []string{ + logger.Info("building envoy+consul image", "image", joint) + logw := logger.Named("docker_envoy_consul").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug}) + + err := run.DockerExecWithStderr(context.TODO(), []string{ "build", + // provenance causes non-idempotent builds, which leads to spurious terraform replacements + "--provenance=false", "--build-arg", "CONSUL_IMAGE=" + n.Images.Consul, "--build-arg", "ENVOY_IMAGE=" + n.Images.Envoy, "-t", joint, "-", - }, logw, strings.NewReader(dockerfileEnvoy)) + }, logw, logw, strings.NewReader(dockerfileEnvoy)) if err != nil { return err } @@ -66,20 +127,42 @@ func DockerImages( cdp := n.Images.LocalDataplaneImage() if _, ok := built[cdp]; cdp != "" && !ok { - logger.Info("building image", "image", cdp) - err := run.DockerExec(context.TODO(), []string{ + logger.Info("building dataplane image", "image", cdp) + logw := logger.Named("docker_dataplane").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug}) + err := run.DockerExecWithStderr(context.TODO(), []string{ "build", + "--provenance=false", "--build-arg", "DATAPLANE_IMAGE=" + n.Images.Dataplane, "-t", cdp, "-", - }, logw, strings.NewReader(dockerfileDataplane)) + }, logw, logw, strings.NewReader(dockerfileDataplane)) if err != nil { return err } built[cdp] = struct{}{} } + + cdpTproxy := n.Images.LocalDataplaneTProxyImage() + if _, ok := built[cdpTproxy]; cdpTproxy != "" && !ok { + logger.Info("building image", "image", cdpTproxy) + logw := logger.Named("docker_dataplane_tproxy").StandardWriter(&hclog.StandardLoggerOptions{ForceLevel: hclog.Debug}) + err := run.DockerExecWithStderr(context.TODO(), []string{ + "build", + "--build-arg", + "DATAPLANE_IMAGE=" + n.Images.Dataplane, + "--build-arg", + "CONSUL_IMAGE=" + n.Images.Consul, + "-t", cdpTproxy, + "-", + }, logw, logw, strings.NewReader(dockerfileDataplaneForTProxy)) + if err != nil { + return err + } + + built[cdpTproxy] = struct{}{} + } } } diff --git a/testing/deployer/sprawl/internal/secrets/store.go b/testing/deployer/sprawl/internal/secrets/store.go index 0cacf88b256e..85e2741e9fc0 100644 --- a/testing/deployer/sprawl/internal/secrets/store.go +++ b/testing/deployer/sprawl/internal/secrets/store.go @@ -18,6 +18,7 @@ const ( GossipKey = "gossip" BootstrapToken = "bootstrap-token" AgentRecovery = "agent-recovery" + CAPEM = "ca-pem" ) func (s *Store) SaveGeneric(cluster, name, value string) { diff --git a/testing/deployer/sprawl/internal/tfgen/agent.go b/testing/deployer/sprawl/internal/tfgen/agent.go index 00e727678353..ee77c09a58bc 100644 --- a/testing/deployer/sprawl/internal/tfgen/agent.go +++ b/testing/deployer/sprawl/internal/tfgen/agent.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/consul/testing/deployer/topology" ) -func (g *Generator) generateAgentHCL(node *topology.Node) string { +func (g *Generator) generateAgentHCL(node *topology.Node, enableV2 bool) string { if !node.IsAgent() { panic("generateAgentHCL only applies to agents") } @@ -35,6 +35,10 @@ func (g *Generator) generateAgentHCL(node *topology.Node) string { b.add("enable_debug", true) b.add("use_streaming_backend", true) + if enableV2 { + b.addSlice("experiments", []string{"resource-apis"}) + } + // speed up leaves b.addBlock("performance", func() { b.add("leave_drain_time", "50ms") diff --git a/testing/deployer/sprawl/internal/tfgen/dns.go b/testing/deployer/sprawl/internal/tfgen/dns.go index 20dca878ebf3..9b03693c8311 100644 --- a/testing/deployer/sprawl/internal/tfgen/dns.go +++ b/testing/deployer/sprawl/internal/tfgen/dns.go @@ -8,8 +8,11 @@ import ( "fmt" "os" "path/filepath" + "sort" "strings" + "golang.org/x/exp/maps" + "github.com/hashicorp/consul/testing/deployer/topology" "github.com/hashicorp/consul/testing/deployer/util" ) @@ -63,17 +66,36 @@ func (g *Generator) writeCoreDNSFiles(net *topology.Network, dnsIPAddress string } } + // Until Consul DNS understands v2, simulate it. + // + // NOTE: this DNS is not quite what consul normally does. It's simpler + // to simulate this format here. + virtualNames := make(map[string][]string) + for id, svcData := range cluster.Services { + if len(svcData.VirtualIps) == 0 { + continue + } + vips := svcData.VirtualIps + + // ----.virtual. + name := fmt.Sprintf("%s--%s--%s", id.Name, id.Namespace, id.Partition) + virtualNames[name] = vips + } + var ( clusterDNSName = cluster.Name + "-consulcluster.lan" - ) + virtualDNSName = "virtual.consul" - corefilePath := filepath.Join(rootdir, "Corefile") - zonefilePath := filepath.Join(rootdir, "servers") + corefilePath = filepath.Join(rootdir, "Corefile") + zonefilePath = filepath.Join(rootdir, "servers") + virtualZonefilePath = filepath.Join(rootdir, "virtual") + ) _, err := UpdateFileIfDifferent( g.logger, generateCoreDNSConfigFile( clusterDNSName, + virtualDNSName, addrs, ), corefilePath, @@ -105,7 +127,25 @@ func (g *Generator) writeCoreDNSFiles(net *topology.Network, dnsIPAddress string return false, nil, fmt.Errorf("error hashing %q: %w", zonefilePath, err) } - return true, []string{corefileHash, zonefileHash}, nil + _, err = UpdateFileIfDifferent( + g.logger, + generateCoreDNSVirtualZoneFile( + dnsIPAddress, + virtualDNSName, + virtualNames, + ), + virtualZonefilePath, + 0644, + ) + if err != nil { + return false, nil, fmt.Errorf("error writing %q: %w", virtualZonefilePath, err) + } + virtualZonefileHash, err := util.HashFile(virtualZonefilePath) + if err != nil { + return false, nil, fmt.Errorf("error hashing %q: %w", virtualZonefilePath, err) + } + + return true, []string{corefileHash, zonefileHash, virtualZonefileHash}, nil } return false, nil, nil @@ -113,6 +153,7 @@ func (g *Generator) writeCoreDNSFiles(net *topology.Network, dnsIPAddress string func generateCoreDNSConfigFile( clusterDNSName string, + virtualDNSName string, addrs []string, ) []byte { serverPart := "" @@ -139,7 +180,14 @@ consul:53 { whoami } -%[2]s +%[2]s:53 { + file /config/virtual %[2]s + log + errors + whoami +} + +%[3]s .:53 { forward . 8.8.8.8:53 @@ -147,7 +195,7 @@ consul:53 { errors whoami } -`, clusterDNSName, serverPart)) +`, clusterDNSName, virtualDNSName, serverPart)) } func generateCoreDNSZoneFile( @@ -178,3 +226,38 @@ server IN A %s ; Consul server return buf.Bytes() } + +func generateCoreDNSVirtualZoneFile( + dnsIPAddress string, + virtualDNSName string, + nameToAddr map[string][]string, +) []byte { + var buf bytes.Buffer + buf.WriteString(fmt.Sprintf(` +$TTL 60 +$ORIGIN %[1]s. +@ IN SOA ns.%[1]s. webmaster.%[1]s. ( + 2017042745 ; serial + 7200 ; refresh (2 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 3600 ; minimum (1 hour) + ) +@ IN NS ns.%[1]s. ; Name server +ns IN A %[2]s ; self +`, virtualDNSName, dnsIPAddress)) + + names := maps.Keys(nameToAddr) + sort.Strings(names) + + for _, name := range names { + vips := nameToAddr[name] + for _, vip := range vips { + buf.WriteString(fmt.Sprintf(` +%s IN A %s ; Consul server +`, name, vip)) + } + } + + return buf.Bytes() +} diff --git a/testing/deployer/sprawl/internal/tfgen/docker_test.go b/testing/deployer/sprawl/internal/tfgen/docker_test.go index 942b87189fca..b657a4d01290 100644 --- a/testing/deployer/sprawl/internal/tfgen/docker_test.go +++ b/testing/deployer/sprawl/internal/tfgen/docker_test.go @@ -12,7 +12,6 @@ import ( func TestDockerImageResourceName(t *testing.T) { fn := DockerImageResourceName - assert.Equal(t, "", fn("")) assert.Equal(t, "abcdefghijklmnopqrstuvwxyz0123456789-", fn("abcdefghijklmnopqrstuvwxyz0123456789-")) assert.Equal(t, "hashicorp-consul-1-15-0", fn("hashicorp/consul:1.15.0")) } diff --git a/testing/deployer/sprawl/internal/tfgen/gen.go b/testing/deployer/sprawl/internal/tfgen/gen.go index f64d7b6a254b..0f38714b0c99 100644 --- a/testing/deployer/sprawl/internal/tfgen/gen.go +++ b/testing/deployer/sprawl/internal/tfgen/gen.go @@ -122,8 +122,10 @@ func (s Step) String() string { } } -func (s Step) StartServers() bool { return s >= StepServers } -func (s Step) StartAgents() bool { return s >= StepAgents } +func (s Step) StartServers() bool { return s >= StepServers } + +func (s Step) StartAgents() bool { return s >= StepAgents } + func (s Step) StartServices() bool { return s >= StepServices } // func (s Step) InitiatePeering() bool { return s >= StepPeering } @@ -260,6 +262,7 @@ func (g *Generator) Generate(step Step) error { addImage("", node.Images.Consul) addImage("", node.Images.EnvoyConsulImage()) addImage("", node.Images.LocalDataplaneImage()) + addImage("", node.Images.LocalDataplaneTProxyImage()) if node.IsAgent() { addVolume(node.DockerName()) diff --git a/testing/deployer/sprawl/internal/tfgen/nodes.go b/testing/deployer/sprawl/internal/tfgen/nodes.go index 33a820a3e32e..4934482d7240 100644 --- a/testing/deployer/sprawl/internal/tfgen/nodes.go +++ b/testing/deployer/sprawl/internal/tfgen/nodes.go @@ -67,7 +67,7 @@ func (g *Generator) generateNodeContainers( }{ terraformPod: pod, ImageResource: DockerImageResourceName(node.Images.Consul), - HCL: g.generateAgentHCL(node), + HCL: g.generateAgentHCL(node, cluster.EnableV2 && node.IsServer()), EnterpriseLicense: g.license, })) } @@ -125,7 +125,11 @@ func (g *Generator) generateNodeContainers( var img string if node.IsDataplane() { tmpl = tfAppDataplaneT - img = DockerImageResourceName(node.Images.LocalDataplaneImage()) + if svc.EnableTransparentProxy { + img = DockerImageResourceName(node.Images.LocalDataplaneTProxyImage()) + } else { + img = DockerImageResourceName(node.Images.LocalDataplaneImage()) + } } else { img = DockerImageResourceName(node.Images.EnvoyConsulImage()) } diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl index 040cabbf1160..f706b6ad2d77 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-app-dataplane.tf.tmpl @@ -1,7 +1,7 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" { name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest + image = docker_image.{{.ImageResource}}.image_id restart = "on-failure" {{- range $k, $v := .Labels }} @@ -17,25 +17,46 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidec read_only = true } +{{ if .Service.EnableTransparentProxy }} + capabilities { + add = ["NET_ADMIN"] + } + entrypoint = [ "/bin/tproxy-startup.sh" ] +{{ end }} + env = [ - "DP_CONSUL_ADDRESSES=server.{{.Node.Cluster}}-consulcluster.lan", - "DP_SERVICE_NODE_NAME={{.Node.PodName}}", - "DP_PROXY_SERVICE_ID={{.Service.ID.Name}}-sidecar-proxy", - {{ if .Enterprise }} - "DP_SERVICE_NAMESPACE={{.Service.ID.Namespace}}", - "DP_SERVICE_PARTITION={{.Service.ID.Partition}}", - {{ end }} - {{ if .Token }} - "DP_CREDENTIAL_TYPE=static", - "DP_CREDENTIAL_STATIC_TOKEN={{.Token}}", - {{ end }} - // for demo purposes - "DP_ENVOY_ADMIN_BIND_ADDRESS=0.0.0.0", - "DP_ENVOY_ADMIN_BIND_PORT=19000", - "DP_LOG_LEVEL=trace", - "DP_CA_CERTS=/consul/config/certs/consul-agent-ca.pem", - "DP_CONSUL_GRPC_PORT=8503", - "DP_TLS_SERVER_NAME=server.{{.Node.Datacenter}}.consul", + "DP_CONSUL_ADDRESSES=server.{{.Node.Cluster}}-consulcluster.lan", +{{ if .Node.IsV2 }} + "DP_PROXY_ID={{.Service.Workload}}", +{{ if .Enterprise }} + "DP_PROXY_NAMESPACE={{.Service.ID.Namespace}}", + "DP_PROXY_PARTITION={{.Service.ID.Partition}}", +{{ end }} +{{ else }} + "DP_SERVICE_NODE_NAME={{.Node.PodName}}", + "DP_PROXY_SERVICE_ID={{.Service.ID.Name}}-sidecar-proxy", +{{ if .Enterprise }} + "DP_SERVICE_NAMESPACE={{.Service.ID.Namespace}}", + "DP_SERVICE_PARTITION={{.Service.ID.Partition}}", +{{ end }} +{{ end }} + +{{ if .Token }} + "DP_CREDENTIAL_TYPE=static", + "DP_CREDENTIAL_STATIC_TOKEN={{.Token}}", +{{ end }} + +{{ if .Service.EnableTransparentProxy }} + "REDIRECT_TRAFFIC_ARGS=-exclude-inbound-port=19000", +{{ end }} + + // for demo purposes + "DP_ENVOY_ADMIN_BIND_ADDRESS=0.0.0.0", + "DP_ENVOY_ADMIN_BIND_PORT=19000", + "DP_LOG_LEVEL=trace", + "DP_CA_CERTS=/consul/config/certs/consul-agent-ca.pem", + "DP_CONSUL_GRPC_PORT=8503", + "DP_TLS_SERVER_NAME=server.{{.Node.Datacenter}}.consul", ] command = [ diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-app-sidecar.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-app-sidecar.tf.tmpl index 15a5f6922691..c368d161043c 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-app-sidecar.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-app-sidecar.tf.tmpl @@ -1,7 +1,7 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" { name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}-sidecar" network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest + image = docker_image.{{.ImageResource}}.image_id restart = "on-failure" {{- range $k, $v := .Labels }} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-app.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-app.tf.tmpl index d6033587b1ea..6cdd7705ea9f 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-app.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-app.tf.tmpl @@ -1,7 +1,7 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" { name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}" network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest + image = docker_image.{{.ImageResource}}.image_id restart = "on-failure" {{- range $k, $v := .Labels }} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-consul.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-consul.tf.tmpl index fac148f29c2b..7b76e0569bc6 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-consul.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-consul.tf.tmpl @@ -1,7 +1,7 @@ resource "docker_container" "{{.Node.DockerName}}" { name = "{{.Node.DockerName}}" network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest + image = docker_image.{{.ImageResource}}.image_id restart = "always" env = [ diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl index 7789376a98f1..97c0d7011d3d 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-coredns.tf.tmpl @@ -1,6 +1,6 @@ resource "docker_container" "{{.DockerNetworkName}}-coredns" { name = "{{.DockerNetworkName}}-coredns" - image = docker_image.coredns.latest + image = docker_image.coredns.image_id restart = "always" dns = ["8.8.8.8"] diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-mgw-dataplane.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-mgw-dataplane.tf.tmpl index 18152e68eb6d..4aac9b5946f0 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-mgw-dataplane.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-mgw-dataplane.tf.tmpl @@ -1,7 +1,7 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" { name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}" network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest + image = docker_image.{{.ImageResource}}.image_id restart = "on-failure" {{- range $k, $v := .Labels }} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-mgw.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-mgw.tf.tmpl index 78c4abe8dfa4..68ccbbd0f1a7 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-mgw.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-mgw.tf.tmpl @@ -1,7 +1,7 @@ resource "docker_container" "{{.Node.DockerName}}-{{.Service.ID.TFString}}" { name = "{{.Node.DockerName}}-{{.Service.ID.TFString}}" network_mode = "container:${docker_container.{{.PodName}}.id}" - image = docker_image.{{.ImageResource}}.latest + image = docker_image.{{.ImageResource}}.image_id restart = "on-failure" {{- range $k, $v := .Labels }} diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl index 1f1627b0719b..ef537f03522a 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-pause.tf.tmpl @@ -1,6 +1,6 @@ resource "docker_container" "{{.PodName}}" { name = "{{.PodName}}" - image = docker_image.pause.latest + image = docker_image.pause.image_id hostname = "{{.PodName}}" restart = "always" dns = ["{{.DNSAddress}}"] diff --git a/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl b/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl index ed44d8343fe8..f4d7fe1d9439 100644 --- a/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl +++ b/testing/deployer/sprawl/internal/tfgen/templates/container-proxy.tf.tmpl @@ -1,6 +1,6 @@ resource "docker_container" "{{.DockerNetworkName}}-forwardproxy" { name = "{{.DockerNetworkName}}-forwardproxy" - image = docker_image.nginx.latest + image = docker_image.nginx.image_id restart = "always" dns = ["8.8.8.8"] diff --git a/testing/deployer/sprawl/peering.go b/testing/deployer/sprawl/peering.go index dd280cc49a29..12c6f3e3ce62 100644 --- a/testing/deployer/sprawl/peering.go +++ b/testing/deployer/sprawl/peering.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "log" "net/http" "strings" "time" @@ -62,6 +63,8 @@ func (s *Sprawl) initPeerings() error { req1.Partition = peering.Accepting.Partition } + s.awaitMeshGateways() + GENTOKEN: resp, _, err := acceptingClient.Peerings().GenerateToken(context.Background(), req1, nil) if err != nil { @@ -108,6 +111,7 @@ func (s *Sprawl) initPeerings() error { } func (s *Sprawl) waitForPeeringEstablishment() error { + s.awaitMeshGateways() var ( logger = s.logger.Named("peering") ) @@ -181,3 +185,64 @@ func (s *Sprawl) checkPeeringDirection(logger hclog.Logger, client *api.Client, } logger.Debug("peering is active", "dur", time.Since(startTime).Round(time.Second)) } + +func (s *Sprawl) awaitMeshGateways() { + startTime := time.Now() + s.logger.Info("awaiting mesh gateways") + // TODO: maybe a better way to do this + mgws := []*topology.Service{} + for _, clu := range s.topology.Clusters { + for _, node := range clu.Nodes { + for _, svc := range node.Services { + if svc.IsMeshGateway { + mgws = append(mgws, svc) + } + } + } + } + + // TODO: parallel + for _, mgw := range mgws { + cl := s.clients[mgw.Node.Cluster] + logger := s.logger.With("cluster", mgw.Node.Cluster, "sid", mgw.ID, "nid", mgw.Node.ID()) + logger.Info("awaiting MGW readiness") + RETRY: + // TODO: not sure if there's a better way to check if the MGW is ready + svcs, _, err := cl.Catalog().Service(mgw.ID.Name, "", &api.QueryOptions{ + Namespace: mgw.ID.Namespace, + Partition: mgw.ID.Partition, + }) + if err != nil { + logger.Debug("fetching MGW service", "err", err) + time.Sleep(time.Second) + goto RETRY + } + if len(svcs) < 1 { + logger.Debug("no MGW service in catalog yet") + time.Sleep(time.Second) + goto RETRY + } + if len(svcs) > 1 { + // not sure when this would happen + log.Fatalf("expected 1 MGW service, actually: %#v", svcs) + } + + entries, _, err := cl.Health().Service(mgw.ID.Name, "", true, &api.QueryOptions{ + Namespace: mgw.ID.Namespace, + Partition: mgw.ID.Partition, + }) + if err != nil { + logger.Debug("fetching MGW checks", "err", err) + time.Sleep(time.Second) + goto RETRY + } + if len(entries) != 1 { + logger.Debug("expected 1 MGW entry", "entries", entries) + time.Sleep(time.Second) + goto RETRY + } + + logger.Debug("MGW ready", "entry", *(entries[0]), "dur", time.Since(startTime).Round(time.Second)) + } + s.logger.Info("mesh gateways ready", "dur", time.Since(startTime).Round(time.Second)) +} diff --git a/testing/deployer/sprawl/resources.go b/testing/deployer/sprawl/resources.go new file mode 100644 index 000000000000..da0ea260ddad --- /dev/null +++ b/testing/deployer/sprawl/resources.go @@ -0,0 +1,22 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package sprawl + +import ( + "github.com/hashicorp/consul/testing/deployer/topology" +) + +func (s *Sprawl) populateInitialResources(cluster *topology.Cluster) error { + if len(cluster.InitialResources) == 0 { + return nil + } + + for _, res := range cluster.InitialResources { + if _, err := s.writeResource(cluster, res); err != nil { + return err + } + } + + return nil +} diff --git a/testing/deployer/sprawl/sprawl.go b/testing/deployer/sprawl/sprawl.go index 3433e1b3dc0a..2cf2c9371acd 100644 --- a/testing/deployer/sprawl/sprawl.go +++ b/testing/deployer/sprawl/sprawl.go @@ -16,9 +16,11 @@ import ( "time" "github.com/hashicorp/consul/api" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-multierror" "github.com/mitchellh/copystructure" + "google.golang.org/grpc" "github.com/hashicorp/consul/testing/deployer/sprawl/internal/runner" "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" @@ -31,10 +33,12 @@ import ( // Sprawl is the definition of a complete running Consul deployment topology. type Sprawl struct { - logger hclog.Logger - runner *runner.Runner - license string - secrets secrets.Store + logger hclog.Logger + // set after initial Launch is complete + launchLogger hclog.Logger + runner *runner.Runner + license string + secrets secrets.Store workdir string @@ -43,7 +47,9 @@ type Sprawl struct { topology *topology.Topology generator *tfgen.Generator - clients map[string]*api.Client // one per cluster + clients map[string]*api.Client // one per cluster + grpcConns map[string]*grpc.ClientConn // one per cluster (when v2 enabled) + grpcConnCancel map[string]func() // one per cluster (when v2 enabled) } // Topology allows access to the topology that defines the resources. Do not @@ -60,6 +66,12 @@ func (s *Sprawl) Config() *topology.Config { return c2 } +// ResourceServiceClientForCluster returns a shared common client that defaults +// to using the management token for this cluster. +func (s *Sprawl) ResourceServiceClientForCluster(clusterName string) pbresource.ResourceServiceClient { + return pbresource.NewResourceServiceClient(s.grpcConns[clusterName]) +} + func (s *Sprawl) HTTPClientForCluster(clusterName string) (*http.Client, error) { cluster, ok := s.topology.Clusters[clusterName] if !ok { @@ -167,10 +179,12 @@ func Launch( } s := &Sprawl{ - logger: logger, - runner: runner, - workdir: workdir, - clients: make(map[string]*api.Client), + logger: logger, + runner: runner, + workdir: workdir, + clients: make(map[string]*api.Client), + grpcConns: make(map[string]*grpc.ClientConn), + grpcConnCancel: make(map[string]func()), } if err := s.ensureLicense(); err != nil { @@ -200,11 +214,20 @@ func Launch( return nil, fmt.Errorf("error gathering diagnostic details: %w", err) } + s.launchLogger = s.logger + return s, nil } func (s *Sprawl) Relaunch( cfg *topology.Config, +) error { + return s.RelaunchWithPhase(cfg, "") +} + +func (s *Sprawl) RelaunchWithPhase( + cfg *topology.Config, + phase string, ) error { // Copy this BEFORE compiling so we capture the original definition, without denorms. var err error @@ -213,6 +236,10 @@ func (s *Sprawl) Relaunch( return err } + if phase != "" { + s.logger = s.launchLogger.Named(phase) + } + newTopology, err := topology.Recompile(s.logger.Named("recompile"), cfg, s.topology) if err != nil { return fmt.Errorf("topology.Compile: %w", err) @@ -235,6 +262,32 @@ func (s *Sprawl) Relaunch( return nil } +// SnapshotSave saves a snapshot of a cluster and restore with the snapshot +func (s *Sprawl) SnapshotSave(clusterName string) error { + cluster, ok := s.topology.Clusters[clusterName] + if !ok { + return fmt.Errorf("no such cluster: %s", clusterName) + } + var ( + client = s.clients[cluster.Name] + ) + snapshot := client.Snapshot() + snap, _, err := snapshot.Save(nil) + if err != nil { + return fmt.Errorf("error saving snapshot: %w", err) + } + s.logger.Info("snapshot saved") + time.Sleep(3 * time.Second) + defer snap.Close() + + // Restore the snapshot. + if err := snapshot.Restore(nil, snap); err != nil { + return fmt.Errorf("error restoring snapshot: %w", err) + } + s.logger.Info("snapshot restored") + return nil +} + // Leader returns the cluster leader agent, or an error if no leader is // available. func (s *Sprawl) Leader(clusterName string) (*topology.Node, error) { diff --git a/testing/deployer/sprawl/sprawltest/sprawltest.go b/testing/deployer/sprawl/sprawltest/sprawltest.go index 7b1e0493d751..d69561286094 100644 --- a/testing/deployer/sprawl/sprawltest/sprawltest.go +++ b/testing/deployer/sprawl/sprawltest/sprawltest.go @@ -13,10 +13,13 @@ import ( "sync" "testing" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/consul/sdk/testutil" "github.com/hashicorp/go-hclog" "github.com/hashicorp/go-multierror" "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" "github.com/hashicorp/consul/testing/deployer/sprawl" "github.com/hashicorp/consul/testing/deployer/sprawl/internal/runner" @@ -206,3 +209,10 @@ func SkipIfTerraformNotPresent(t *testing.T) { t.Skipf("%q not found on $PATH - download and install to run this test", terraformBinaryName) } } + +func MustSetResourceData(t *testing.T, res *pbresource.Resource, data proto.Message) *pbresource.Resource { + anyData, err := anypb.New(data) + require.NoError(t, err) + res.Data = anyData + return res +} diff --git a/testing/deployer/sprawl/sprawltest/test_test.go b/testing/deployer/sprawl/sprawltest/test_test.go index 1bb69ea77efe..8a098c92ab2b 100644 --- a/testing/deployer/sprawl/sprawltest/test_test.go +++ b/testing/deployer/sprawl/sprawltest/test_test.go @@ -8,17 +8,160 @@ import ( "testing" "github.com/hashicorp/consul/api" + pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/stretchr/testify/require" "github.com/hashicorp/consul/testing/deployer/sprawl/sprawltest" "github.com/hashicorp/consul/testing/deployer/topology" ) +func TestSprawl_CatalogV2(t *testing.T) { + serversDC1 := newTopologyServerSet("dc1-server", 3, []string{"dc1", "wan"}, nil) + + cfg := &topology.Config{ + Images: topology.Images{ + ConsulCE: "hashicorppreview/consul:1.17-dev", + ConsulEnterprise: "hashicorppreview/consul-enterprise:1.17-dev", + Dataplane: "hashicorppreview/consul-dataplane:1.3-dev", + }, + Networks: []*topology.Network{ + {Name: "dc1"}, + {Name: "wan", Type: "wan"}, + }, + Clusters: []*topology.Cluster{ + { + Enterprise: true, + Name: "dc1", + Nodes: topology.MergeSlices(serversDC1, []*topology.Node{ + { + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Name: "dc1-client1", + Services: []*topology.Service{ + { + ID: topology.ServiceID{Name: "ping"}, + Image: "rboyer/pingpong:latest", + Port: 8080, + EnvoyAdminPort: 19000, + Command: []string{ + "-bind", "0.0.0.0:8080", + "-dial", "127.0.0.1:9090", + "-pong-chaos", + "-dialfreq", "250ms", + "-name", "ping", + }, + Upstreams: []*topology.Upstream{{ + ID: topology.ServiceID{Name: "pong"}, + LocalPort: 9090, + }}, + }, + }, + }, + { + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Name: "dc1-client2", + Services: []*topology.Service{ + { + ID: topology.ServiceID{Name: "pong"}, + Image: "rboyer/pingpong:latest", + Port: 8080, + EnvoyAdminPort: 19000, + Command: []string{ + "-bind", "0.0.0.0:8080", + "-dial", "127.0.0.1:9090", + "-pong-chaos", + "-dialfreq", "250ms", + "-name", "pong", + }, + Upstreams: []*topology.Upstream{{ + ID: topology.ServiceID{Name: "ping"}, + LocalPort: 9090, + }}, + }, + }, + }, + }), + InitialResources: []*pbresource.Resource{ + sprawltest.MustSetResourceData(t, &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbmesh.HTTPRouteType, + Name: "test-http-route", + }, + }, &pbmesh.HTTPRoute{ + ParentRefs: []*pbmesh.ParentReference{{ + Ref: &pbresource.Reference{ + Type: pbcatalog.ServiceType, + Name: "test", + }, + }}, + }), + sprawltest.MustSetResourceData(t, &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbauth.TrafficPermissionsType, + Name: "ping-perms", + }, + }, &pbauth.TrafficPermissions{ + Destination: &pbauth.Destination{ + IdentityName: "ping", + }, + Action: pbauth.Action_ACTION_ALLOW, + Permissions: []*pbauth.Permission{{ + Sources: []*pbauth.Source{{ + IdentityName: "pong", + }}, + }}, + }), + sprawltest.MustSetResourceData(t, &pbresource.Resource{ + Id: &pbresource.ID{ + Type: pbauth.TrafficPermissionsType, + Name: "pong-perms", + }, + }, &pbauth.TrafficPermissions{ + Destination: &pbauth.Destination{ + IdentityName: "pong", + }, + Action: pbauth.Action_ACTION_ALLOW, + Permissions: []*pbauth.Permission{{ + Sources: []*pbauth.Source{{ + IdentityName: "ping", + }}, + }}, + }), + }, + }, + }, + } + + sp := sprawltest.Launch(t, cfg) + + for _, cluster := range sp.Topology().Clusters { + leader, err := sp.Leader(cluster.Name) + require.NoError(t, err) + t.Logf("%s: leader = %s", cluster.Name, leader.ID()) + + followers, err := sp.Followers(cluster.Name) + require.NoError(t, err) + for _, f := range followers { + t.Logf("%s: follower = %s", cluster.Name, f.ID()) + } + } +} + func TestSprawl(t *testing.T) { serversDC1 := newTopologyServerSet("dc1-server", 3, []string{"dc1", "wan"}, nil) serversDC2 := newTopologyServerSet("dc2-server", 3, []string{"dc2", "wan"}, nil) cfg := &topology.Config{ + Images: topology.Images{ + // ConsulEnterprise: "consul-dev:latest", + ConsulCE: "hashicorppreview/consul:1.17-dev", + ConsulEnterprise: "hashicorppreview/consul-enterprise:1.17-dev", + Dataplane: "hashicorppreview/consul-dataplane:1.3-dev", + }, Networks: []*topology.Network{ {Name: "dc1"}, {Name: "dc2"}, @@ -116,6 +259,31 @@ func TestSprawl(t *testing.T) { }, }, }, + { + Kind: topology.NodeKindDataplane, + Version: topology.NodeVersionV2, + Name: "dc2-client3", + Services: []*topology.Service{ + { + ID: topology.ServiceID{Name: "pong"}, + Image: "rboyer/pingpong:latest", + Port: 8080, + EnvoyAdminPort: 19000, + Command: []string{ + "-bind", "0.0.0.0:8080", + "-dial", "127.0.0.1:9090", + "-pong-chaos", + "-dialfreq", "250ms", + "-name", "pong", + }, + Upstreams: []*topology.Upstream{{ + ID: topology.ServiceID{Name: "ping"}, + LocalPort: 9090, + Peer: "peer-dc1-default", + }}, + }, + }, + }, }), InitialConfigEntries: []api.ConfigEntry{ &api.ExportedServicesConfigEntry{ diff --git a/testing/deployer/sprawl/tls.go b/testing/deployer/sprawl/tls.go index bc5489206c7b..d1e3fd683688 100644 --- a/testing/deployer/sprawl/tls.go +++ b/testing/deployer/sprawl/tls.go @@ -9,6 +9,7 @@ import ( "fmt" "io" + "github.com/hashicorp/consul/testing/deployer/sprawl/internal/secrets" "github.com/hashicorp/consul/testing/deployer/topology" ) @@ -113,6 +114,29 @@ fi if err != nil { return fmt.Errorf("could not create all necessary TLS certificates in docker volume: %v", err) } + + var capture bytes.Buffer + err = s.runner.DockerExec(ctx, []string{"run", + "--rm", + "-i", + "--net=none", + "-u", consulUserArg, + "-v", cluster.TLSVolumeName + ":/data", + "-w", "/data", + "busybox:1.34", + "cat", + "/data/consul-agent-ca.pem", + }, &capture, nil) + if err != nil { + return fmt.Errorf("could not read CA PEM from docker volume: %v", err) + } + + caPEM := capture.String() + if caPEM == "" { + return fmt.Errorf("found empty CA PEM") + } + + s.secrets.SaveGeneric(cluster.Name, secrets.CAPEM, caPEM) } return nil diff --git a/testing/deployer/topology/compile.go b/testing/deployer/topology/compile.go index 98f1c1e917e8..148968d6aeaf 100644 --- a/testing/deployer/topology/compile.go +++ b/testing/deployer/topology/compile.go @@ -13,10 +13,17 @@ import ( "sort" "github.com/google/go-cmp/cmp" + pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" "github.com/hashicorp/go-hclog" + "golang.org/x/exp/maps" + + "github.com/hashicorp/consul/testing/deployer/util" ) -const DockerPrefix = "consulcluster" +const DockerPrefix = "cslc" // ConSuLCluster func Compile(logger hclog.Logger, raw *Config) (*Topology, error) { return compile(logger, raw, nil) @@ -122,6 +129,22 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error return nil, fmt.Errorf("cluster %q has no nodes", c.Name) } + if len(c.Services) == 0 { // always initialize this regardless of v2-ness, because we might late-enable it below + c.Services = make(map[ServiceID]*pbcatalog.Service) + } + + var implicitV2Services bool + if len(c.Services) > 0 { + c.EnableV2 = true + for name, svc := range c.Services { + if svc.Workloads != nil { + return nil, fmt.Errorf("the workloads field for v2 service %q is not user settable", name) + } + } + } else { + implicitV2Services = true + } + if c.TLSVolumeName != "" { return nil, fmt.Errorf("user cannot specify the TLSVolumeName field") } @@ -149,6 +172,39 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error addTenancy(ce.GetPartition(), ce.GetNamespace()) } + if len(c.InitialResources) > 0 { + c.EnableV2 = true + } + for _, res := range c.InitialResources { + if res.Id.Tenancy == nil { + res.Id.Tenancy = &pbresource.Tenancy{} + } + switch res.Id.Tenancy.PeerName { + case "", "local": + default: + return nil, fmt.Errorf("resources cannot target non-local peers") + } + res.Id.Tenancy.Partition = PartitionOrDefault(res.Id.Tenancy.Partition) + res.Id.Tenancy.Namespace = NamespaceOrDefault(res.Id.Tenancy.Namespace) + + switch { + case util.EqualType(pbauth.ComputedTrafficPermissionsType, res.Id.GetType()), + util.EqualType(pbauth.WorkloadIdentityType, res.Id.GetType()): + fallthrough + case util.EqualType(pbmesh.ComputedRoutesType, res.Id.GetType()), + util.EqualType(pbmesh.ProxyStateTemplateType, res.Id.GetType()): + fallthrough + case util.EqualType(pbcatalog.HealthChecksType, res.Id.GetType()), + util.EqualType(pbcatalog.HealthStatusType, res.Id.GetType()), + util.EqualType(pbcatalog.NodeType, res.Id.GetType()), + util.EqualType(pbcatalog.ServiceEndpointsType, res.Id.GetType()), + util.EqualType(pbcatalog.WorkloadType, res.Id.GetType()): + return nil, fmt.Errorf("you should not create a resource of type %q this way", util.TypeToString(res.Id.Type)) + } + + addTenancy(res.Id.Tenancy.Partition, res.Id.Tenancy.Namespace) + } + seenNodes := make(map[NodeID]struct{}) for _, n := range c.Nodes { if n.Name == "" { @@ -164,6 +220,20 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error return nil, fmt.Errorf("cluster %q node %q has invalid kind: %s", c.Name, n.Name, n.Kind) } + if n.Version == NodeVersionUnknown { + n.Version = NodeVersionV1 + } + switch n.Version { + case NodeVersionV1: + case NodeVersionV2: + if n.Kind == NodeKindClient { + return nil, fmt.Errorf("v2 does not support client agents at this time") + } + c.EnableV2 = true + default: + return nil, fmt.Errorf("cluster %q node %q has invalid version: %s", c.Name, n.Name, n.Version) + } + n.Partition = PartitionOrDefault(n.Partition) if !IsValidLabel(n.Partition) { return nil, fmt.Errorf("node partition is not valid: %s", n.Partition) @@ -247,6 +317,13 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error return nil, fmt.Errorf("cluster %q node %q has more than one public address", c.Name, n.Name) } + if n.IsDataplane() && len(n.Services) > 1 { + // Our use of consul-dataplane here is supposed to mimic that + // of consul-k8s, which ultimately has one IP per Service, so + // we introduce the same limitation here. + return nil, fmt.Errorf("cluster %q node %q uses dataplane, but has more than one service", c.Name, n.Name) + } + seenServices := make(map[ServiceID]struct{}) for _, svc := range n.Services { if n.IsAgent() { @@ -257,6 +334,10 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error // Denormalize svc.Node = n + svc.NodeVersion = n.Version + if n.IsV2() { + svc.Workload = svc.ID.Name + "-" + n.PodName() + } if !IsValidLabel(svc.ID.Partition) { return nil, fmt.Errorf("service partition is not valid: %s", svc.ID.Partition) @@ -313,7 +394,7 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error // return nil, fmt.Errorf("service has invalid protocol: %s", svc.Protocol) // } - for _, u := range svc.Upstreams { + defaultUpstream := func(u *Upstream) error { // Default to that of the enclosing service. if u.Peer == "" { if u.ID.Partition == "" { @@ -330,15 +411,135 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error foundPeerNames[c.Name][u.Peer] = struct{}{} } - if u.ID.Name == "" { - return nil, fmt.Errorf("upstream service name is required") - } addTenancy(u.ID.Partition, u.ID.Namespace) + + if u.Implied { + if u.PortName == "" { + return fmt.Errorf("implicit upstreams must use port names in v2") + } + } else { + if u.LocalAddress == "" { + // v1 defaults to 127.0.0.1 but v2 does not. Safe to do this generally though. + u.LocalAddress = "127.0.0.1" + } + if u.PortName != "" && n.IsV1() { + return fmt.Errorf("explicit upstreams cannot use port names in v1") + } + if u.PortName == "" && n.IsV2() { + // Assume this is a v1->v2 conversion and name it. + u.PortName = "legacy" + } + } + + return nil + } + + for _, u := range svc.Upstreams { + if err := defaultUpstream(u); err != nil { + return nil, err + } + } + + if n.IsV2() { + for _, u := range svc.ImpliedUpstreams { + u.Implied = true + if err := defaultUpstream(u); err != nil { + return nil, err + } + } + } else { + if len(svc.ImpliedUpstreams) > 0 { + return nil, fmt.Errorf("v1 does not support implied upstreams yet") + } } if err := svc.Validate(); err != nil { return nil, fmt.Errorf("cluster %q node %q service %q is not valid: %w", c.Name, n.Name, svc.ID.String(), err) } + + if svc.EnableTransparentProxy && !n.IsDataplane() { + return nil, fmt.Errorf("cannot enable tproxy on a non-dataplane node") + } + + if n.IsV2() { + if implicitV2Services { + svc.V2Services = []string{svc.ID.Name} + + var svcPorts []*pbcatalog.ServicePort + for name, cfg := range svc.Ports { + svcPorts = append(svcPorts, &pbcatalog.ServicePort{ + TargetPort: name, + Protocol: cfg.ActualProtocol, + }) + } + + v2svc := &pbcatalog.Service{ + Workloads: &pbcatalog.WorkloadSelector{}, + Ports: svcPorts, + } + + prev, ok := c.Services[svc.ID] + if !ok { + c.Services[svc.ID] = v2svc + prev = v2svc + } + if prev.Workloads == nil { + prev.Workloads = &pbcatalog.WorkloadSelector{} + } + prev.Workloads.Names = append(prev.Workloads.Names, svc.Workload) + + } else { + for _, name := range svc.V2Services { + v2ID := NewServiceID(name, svc.ID.Namespace, svc.ID.Partition) + + v2svc, ok := c.Services[v2ID] + if !ok { + return nil, fmt.Errorf("cluster %q node %q service %q has a v2 service reference that does not exist %q", + c.Name, n.Name, svc.ID.String(), name) + } + if v2svc.Workloads == nil { + v2svc.Workloads = &pbcatalog.WorkloadSelector{} + } + v2svc.Workloads.Names = append(v2svc.Workloads.Names, svc.Workload) + } + } + + if svc.WorkloadIdentity == "" { + svc.WorkloadIdentity = svc.ID.Name + } + } else { + if len(svc.V2Services) > 0 { + return nil, fmt.Errorf("cannot specify v2 services for v1") + } + if svc.WorkloadIdentity != "" { + return nil, fmt.Errorf("cannot specify workload identities for v1") + } + } + } + } + + if err := assignVirtualIPs(c); err != nil { + return nil, err + } + + if c.EnableV2 { + // Populate the VirtualPort field on all implied upstreams. + for _, n := range c.Nodes { + for _, svc := range n.Services { + for _, u := range svc.ImpliedUpstreams { + res, ok := c.Services[u.ID] + if ok { + for _, sp := range res.Ports { + if sp.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { + continue + } + if sp.TargetPort == u.PortName { + u.VirtualPort = sp.VirtualPort + } + } + } + } + } } } @@ -467,6 +668,21 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error // this helps in generating fortio assertions; otherwise field is ignored u.ID.Partition = remotePeer.Link.Partition } + for _, u := range svc.ImpliedUpstreams { + if u.Peer == "" { + u.Cluster = c.Name + u.Peering = nil + continue + } + remotePeer, ok := c.Peerings[u.Peer] + if !ok { + return nil, fmt.Errorf("not possible") + } + u.Cluster = remotePeer.Link.Name + u.Peering = remotePeer.Link + // this helps in generating fortio assertions; otherwise field is ignored + u.ID.Partition = remotePeer.Link.Partition + } } } } @@ -519,6 +735,9 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error if len(newCluster.InitialConfigEntries) > 0 { logger.Warn("initial config entries were provided, but are skipped on recompile") } + if len(newCluster.InitialResources) > 0 { + logger.Warn("initial resources were provided, but are skipped on recompile") + } // Check NODES if err := inheritAndValidateNodes(oldCluster.Nodes, newCluster.Nodes); err != nil { @@ -530,6 +749,51 @@ func compile(logger hclog.Logger, raw *Config, prev *Topology) (*Topology, error return t, nil } +func assignVirtualIPs(c *Cluster) error { + lastVIPIndex := 1 + for _, svcData := range c.Services { + lastVIPIndex++ + if lastVIPIndex > 250 { + return fmt.Errorf("too many ips using this approach to VIPs") + } + svcData.VirtualIps = []string{ + fmt.Sprintf("10.244.0.%d", lastVIPIndex), + } + + // populate virtual ports where we forgot them + var ( + usedPorts = make(map[uint32]struct{}) + next = uint32(8080) + ) + for _, sp := range svcData.Ports { + if sp.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { + continue + } + if sp.VirtualPort > 0 { + usedPorts[sp.VirtualPort] = struct{}{} + } + } + for _, sp := range svcData.Ports { + if sp.Protocol == pbcatalog.Protocol_PROTOCOL_MESH { + continue + } + if sp.VirtualPort > 0 { + continue + } + RETRY: + attempt := next + next++ + _, used := usedPorts[attempt] + if used { + goto RETRY + } + usedPorts[attempt] = struct{}{} + sp.VirtualPort = attempt + } + } + return nil +} + const permutedWarning = "use the disabled node kind if you want to ignore a node" func inheritAndValidateNodes( @@ -553,6 +817,7 @@ func inheritAndValidateNodes( } if currNode.Node.Kind != node.Kind || + currNode.Node.Version != node.Version || currNode.Node.Partition != node.Partition || currNode.Node.Name != node.Name || currNode.Node.Index != node.Index || @@ -589,6 +854,7 @@ func inheritAndValidateNodes( if currSvc.ID != svc.ID || currSvc.Port != svc.Port || + !maps.Equal(currSvc.Ports, svc.Ports) || currSvc.EnvoyAdminPort != svc.EnvoyAdminPort || currSvc.EnvoyPublicListenerPort != svc.EnvoyPublicListenerPort || isSame(currSvc.Command, svc.Command) != nil || diff --git a/testing/deployer/topology/default_cdp.go b/testing/deployer/topology/default_cdp.go deleted file mode 100644 index f20df3d1a9cc..000000000000 --- a/testing/deployer/topology/default_cdp.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -const DefaultDataplaneImage = "hashicorp/consul-dataplane:1.2.1" diff --git a/testing/deployer/topology/default_consul.go b/testing/deployer/topology/default_consul.go deleted file mode 100644 index f9542f16643d..000000000000 --- a/testing/deployer/topology/default_consul.go +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: BUSL-1.1 - -package topology - -const DefaultConsulImage = "hashicorp/consul:1.15.2" -const DefaultConsulEnterpriseImage = "hashicorp/consul-enterprise:1.15.2-ent" diff --git a/testing/deployer/topology/default_versions.go b/testing/deployer/topology/default_versions.go new file mode 100644 index 000000000000..b35bb7ecfaa2 --- /dev/null +++ b/testing/deployer/topology/default_versions.go @@ -0,0 +1,13 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +// Code generated by update-latest-versions.sh. DO NOT EDIT. + +package topology + +const ( + DefaultConsulImage = "hashicorp/consul:1.16.2" + DefaultConsulEnterpriseImage = "hashicorp/consul-enterprise:1.16.2-ent" + DefaultEnvoyImage = "envoyproxy/envoy:v1.26.4" + DefaultDataplaneImage = "hashicorp/consul-dataplane:1.2.2" +) diff --git a/testing/deployer/topology/default_envoy.go b/testing/deployer/topology/generate.go similarity index 62% rename from testing/deployer/topology/default_envoy.go rename to testing/deployer/topology/generate.go index c557a318a17f..f9d6e26c3acb 100644 --- a/testing/deployer/topology/default_envoy.go +++ b/testing/deployer/topology/generate.go @@ -3,4 +3,4 @@ package topology -const DefaultEnvoyImage = "envoyproxy/envoy:v1.25.1" +//go:generate ../update-latest-versions.sh diff --git a/testing/deployer/topology/ids.go b/testing/deployer/topology/ids.go index 3f964b12548e..73106ff4c91b 100644 --- a/testing/deployer/topology/ids.go +++ b/testing/deployer/topology/ids.go @@ -69,6 +69,7 @@ func (id NodeID) String() string { func (id NodeID) ACLString() string { return fmt.Sprintf("%s--%s", id.Partition, id.Name) } + func (id NodeID) TFString() string { return id.ACLString() } @@ -111,16 +112,26 @@ func (id ServiceID) String() string { func (id ServiceID) ACLString() string { return fmt.Sprintf("%s--%s--%s", id.Partition, id.Namespace, id.Name) } + func (id ServiceID) TFString() string { return id.ACLString() } +func (id ServiceID) PartitionOrDefault() string { + return PartitionOrDefault(id.Partition) +} + +func (id ServiceID) NamespaceOrDefault() string { + return NamespaceOrDefault(id.Namespace) +} + func PartitionOrDefault(name string) string { if name == "" { return "default" } return name } + func NamespaceOrDefault(name string) string { if name == "" { return "default" diff --git a/testing/deployer/topology/images.go b/testing/deployer/topology/images.go index 836ddb091c91..ba20ba17d8c7 100644 --- a/testing/deployer/topology/images.go +++ b/testing/deployer/topology/images.go @@ -34,13 +34,21 @@ func (i Images) LocalDataplaneImage() string { return "local/" + name + ":" + tag } +func (i Images) LocalDataplaneTProxyImage() string { + return spliceImageNamesAndTags(i.Dataplane, i.Consul, "tproxy") +} + func (i Images) EnvoyConsulImage() string { - if i.Consul == "" || i.Envoy == "" { + return spliceImageNamesAndTags(i.Consul, i.Envoy, "") +} + +func spliceImageNamesAndTags(base1, base2, nameSuffix string) string { + if base1 == "" || base2 == "" { return "" } - img1, tag1, ok1 := strings.Cut(i.Consul, ":") - img2, tag2, ok2 := strings.Cut(i.Envoy, ":") + img1, tag1, ok1 := strings.Cut(base1, ":") + img2, tag2, ok2 := strings.Cut(base2, ":") if !ok1 { tag1 = "latest" } @@ -62,8 +70,12 @@ func (i Images) EnvoyConsulImage() string { name2 = repo2 } + if nameSuffix != "" { + nameSuffix = "-" + nameSuffix + } + // ex: local/hashicorp-consul-and-envoyproxy-envoy:1.15.0-with-v1.26.2 - return "local/" + name1 + "-and-" + name2 + ":" + tag1 + "-with-" + tag2 + return "local/" + name1 + "-and-" + name2 + nameSuffix + ":" + tag1 + "-with-" + tag2 } // TODO: what is this for and why do we need to do this and why is it named this? diff --git a/testing/deployer/topology/relationships.go b/testing/deployer/topology/relationships.go new file mode 100644 index 000000000000..8448451f3f07 --- /dev/null +++ b/testing/deployer/topology/relationships.go @@ -0,0 +1,92 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: BUSL-1.1 + +package topology + +import ( + "bytes" + "fmt" + "text/tabwriter" +) + +// ComputeRelationships will analyze a full topology and generate all of the +// downstream/upstream information for all of them. +func (t *Topology) ComputeRelationships() []Relationship { + var out []Relationship + for _, cluster := range t.Clusters { + for _, n := range cluster.Nodes { + for _, s := range n.Services { + for _, u := range s.Upstreams { + out = append(out, Relationship{ + Caller: s, + Upstream: u, + }) + } + for _, u := range s.ImpliedUpstreams { + out = append(out, Relationship{ + Caller: s, + Upstream: u, + }) + } + } + } + } + return out +} + +// RenderRelationships will take the output of ComputeRelationships and display +// it in tabular form. +func RenderRelationships(ships []Relationship) string { + var buf bytes.Buffer + w := tabwriter.NewWriter(&buf, 0, 0, 3, ' ', tabwriter.Debug) + fmt.Fprintf(w, "DOWN\tnode\tservice\tport\tUP\tservice\t\n") + for _, r := range ships { + suffix := "" + if r.Upstream.Implied { + suffix = " (implied)" + } + fmt.Fprintf(w, + "%s\t%s\t%s\t%d\t%s\t%s\t\n", + r.downCluster(), + r.Caller.Node.ID().String(), + r.Caller.ID.String(), + r.Upstream.LocalPort, + r.upCluster(), + r.Upstream.ID.String()+suffix, + ) + } + fmt.Fprintf(w, "\t\t\t\t\t\t\n") + + w.Flush() + return buf.String() +} + +type Relationship struct { + Caller *Service + Upstream *Upstream +} + +func (r Relationship) String() string { + suffix := "" + if r.Upstream.PortName != "" { + suffix = " port " + r.Upstream.PortName + } + return fmt.Sprintf( + "%s on %s in %s via :%d => %s in %s%s", + r.Caller.ID.String(), + r.Caller.Node.ID().String(), + r.downCluster(), + r.Upstream.LocalPort, + r.Upstream.ID.String(), + r.upCluster(), + suffix, + ) +} + +func (r Relationship) downCluster() string { + return r.Caller.Node.Cluster +} + +func (r Relationship) upCluster() string { + return r.Upstream.Cluster +} diff --git a/testing/deployer/topology/topology.go b/testing/deployer/topology/topology.go index a71dbaa4514f..b59045b564b4 100644 --- a/testing/deployer/topology/topology.go +++ b/testing/deployer/topology/topology.go @@ -10,8 +10,11 @@ import ( "net/netip" "reflect" "sort" + "strings" "github.com/hashicorp/consul/api" + pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" + "github.com/hashicorp/consul/proto-public/pbresource" ) type Topology struct { @@ -108,6 +111,45 @@ func (c *Config) Cluster(name string) *Cluster { return nil } +// DisableNode is a no-op if the node is already disabled. +func (c *Config) DisableNode(clusterName string, nid NodeID) (bool, error) { + cluster := c.Cluster(clusterName) + if cluster == nil { + return false, fmt.Errorf("no such cluster: %q", clusterName) + } + + for _, n := range cluster.Nodes { + if n.ID() == nid { + if n.Disabled { + return false, nil + } + n.Disabled = true + return true, nil + } + } + + return false, fmt.Errorf("expected to find nodeID %q in cluster %q", nid.String(), clusterName) +} + +// EnableNode is a no-op if the node is already enabled. +func (c *Config) EnableNode(clusterName string, nid NodeID) (bool, error) { + cluster := c.Cluster(clusterName) + if cluster == nil { + return false, fmt.Errorf("no such cluster: %q", clusterName) + } + + for _, n := range cluster.Nodes { + if n.ID() == nid { + if !n.Disabled { + return false, nil + } + n.Disabled = false + return true, nil + } + } + return false, fmt.Errorf("expected to find nodeID %q in cluster %q", nid.String(), clusterName) +} + type Network struct { Type string // lan/wan ; empty means lan Name string // logical name @@ -198,6 +240,14 @@ type Cluster struct { // components. Enterprise bool `json:",omitempty"` + // Services is a forward declaration of V2 services. This goes in hand with + // the V2Services field on the Service (instance) struct. + // + // Use of this is optional. If you elect not to use it, then v2 Services + // definitions are inferred from the list of service instances defined on + // the nodes in this cluster. + Services map[ServiceID]*pbcatalog.Service `json:"omitempty"` + // Nodes is the definition of the nodes (agent-less and agent-ful). Nodes []*Node @@ -212,11 +262,16 @@ type Cluster struct { // create multiple peer clusters with identical datacenter names. Datacenter string - // InitialConfigEntries is a convenience function to have some config + // InitialConfigEntries is a convenience mechanism to have some config // entries created after the servers start up but before the rest of the // topology comes up. InitialConfigEntries []api.ConfigEntry `json:",omitempty"` + // InitialResources is a convenience mechanism to have some resources + // created after the servers start up but before the rest of the topology + // comes up. + InitialResources []*pbresource.Resource `json:",omitempty"` + // TLSVolumeName is the docker volume name containing the various certs // generated by 'consul tls cert create' // @@ -227,6 +282,10 @@ type Cluster struct { // // Denormalized during compile. Peerings map[string]*PeerCluster `json:",omitempty"` + + // EnableV2 activates V2 on the servers. If any node in the cluster needs + // V2 this will be turned on automatically. + EnableV2 bool `json:",omitempty"` } func (c *Cluster) inheritFromExisting(existing *Cluster) { @@ -422,9 +481,18 @@ const ( NodeKindDataplane NodeKind = "dataplane" ) +type NodeVersion string + +const ( + NodeVersionUnknown NodeVersion = "" + NodeVersionV1 NodeVersion = "v1" + NodeVersionV2 NodeVersion = "v2" +) + // TODO: rename pod type Node struct { Kind NodeKind + Version NodeVersion Partition string // will be not empty Name string // logical name @@ -462,6 +530,9 @@ func (n *Node) DockerName() string { } func (n *Node) ExposedPort(internalPort int) int { + if internalPort == 0 { + return 0 + } return n.usedPorts[internalPort] } @@ -515,7 +586,7 @@ func (n *Node) LocalAddress() string { for _, a := range n.Addresses { if a.IsLocal() { if a.IPAddress == "" { - panic("node has no assigned local address") + panic("node has no assigned local address: " + n.Name) } return a.IPAddress } @@ -538,7 +609,7 @@ func (n *Node) LocalProxyPort() int { if a.ProxyPort > 0 { return a.ProxyPort } - panic("node has no assigned local address") + panic("node has no assigned local address: " + n.Name) } } panic("node has no local network") @@ -568,6 +639,14 @@ func (n *Node) PublicProxyPort() int { panic("node has no public network") } +func (n *Node) IsV2() bool { + return n.Version == NodeVersionV2 +} + +func (n *Node) IsV1() bool { + return !n.IsV2() +} + func (n *Node) IsServer() bool { return n.Kind == NodeKindServer } @@ -639,11 +718,63 @@ type ServiceAndNode struct { Node *Node } +// Protocol is a convenience function to use when authoring topology configs. +func Protocol(s string) (pbcatalog.Protocol, bool) { + switch strings.ToLower(s) { + case "tcp": + return pbcatalog.Protocol_PROTOCOL_TCP, true + case "http": + return pbcatalog.Protocol_PROTOCOL_HTTP, true + case "http2": + return pbcatalog.Protocol_PROTOCOL_HTTP2, true + case "grpc": + return pbcatalog.Protocol_PROTOCOL_GRPC, true + case "mesh": + return pbcatalog.Protocol_PROTOCOL_MESH, true + default: + return pbcatalog.Protocol_PROTOCOL_UNSPECIFIED, false + } +} + +type Port struct { + Number int + Protocol string `json:",omitempty"` + + // denormalized at topology compile + ActualProtocol pbcatalog.Protocol `json:",omitempty"` +} + +// TODO(rb): really this should now be called "workload" or "instance" type Service struct { - ID ServiceID - Image string - Port int - ExposedPort int `json:",omitempty"` + ID ServiceID + Image string + + // Port is the v1 single-port of this service. + Port int `json:",omitempty"` + + // Ports is the v2 multi-port list for this service. + // + // This only applies for multi-port (v2). + Ports map[string]*Port `json:",omitempty"` + + // V2Services contains service names (which are merged with the tenancy + // info from ID) to resolve services in the Services slice in the Cluster + // definition. + // + // If omitted it is inferred that the ID.Name field is the singular service + // for this workload. + // + // This only applies for multi-port (v2). + V2Services []string `json:",omitempty"` + + // WorkloadIdentity contains named WorkloadIdentity to assign to this + // workload. + // + // If omitted it is inferred that the ID.Name field is the singular + // identity for this workload. + // + // This only applies for multi-port (v2). + WorkloadIdentity string `json:",omitempty"` Disabled bool `json:",omitempty"` // TODO @@ -662,22 +793,68 @@ type Service struct { Command []string `json:",omitempty"` // optional Env []string `json:",omitempty"` // optional - DisableServiceMesh bool `json:",omitempty"` - IsMeshGateway bool `json:",omitempty"` - Upstreams []*Upstream + EnableTransparentProxy bool `json:",omitempty"` + DisableServiceMesh bool `json:",omitempty"` + IsMeshGateway bool `json:",omitempty"` + Upstreams []*Upstream `json:",omitempty"` + ImpliedUpstreams []*Upstream `json:",omitempty"` // denormalized at topology compile - Node *Node `json:"-"` + Node *Node `json:"-"` + NodeVersion NodeVersion `json:"-"` + Workload string `json:"-"` +} + +func (s *Service) ExposedPort(name string) int { + if s.Node == nil { + panic("ExposedPort cannot be called until after Compile") + } + + var internalPort int + if name == "" { + internalPort = s.Port + } else { + port, ok := s.Ports[name] + if !ok { + panic("port with name " + name + " not present on service") + } + internalPort = port.Number + } + + return s.Node.ExposedPort(internalPort) +} + +func (s *Service) PortOrDefault(name string) int { + if len(s.Ports) > 0 { + return s.Ports[name].Number + } + return s.Port +} + +func (s *Service) IsV2() bool { + return s.NodeVersion == NodeVersionV2 +} + +func (s *Service) IsV1() bool { + return !s.IsV2() } func (s *Service) inheritFromExisting(existing *Service) { - s.ExposedPort = existing.ExposedPort s.ExposedEnvoyAdminPort = existing.ExposedEnvoyAdminPort } func (s *Service) ports() []int { var out []int - if s.Port > 0 { + if len(s.Ports) > 0 { + seen := make(map[int]struct{}) + for _, port := range s.Ports { + if _, ok := seen[port.Number]; !ok { + // It's totally fine to expose the same port twice in a workload. + seen[port.Number] = struct{}{} + out = append(out, port.Number) + } + } + } else if s.Port > 0 { out = append(out, s.Port) } if s.EnvoyAdminPort > 0 { @@ -699,7 +876,6 @@ func (s *Service) HasCheck() bool { } func (s *Service) DigestExposedPorts(ports map[int]int) { - s.ExposedPort = ports[s.Port] if s.EnvoyAdminPort > 0 { s.ExposedEnvoyAdminPort = ports[s.EnvoyAdminPort] } else { @@ -714,8 +890,54 @@ func (s *Service) Validate() error { if s.Image == "" && !s.IsMeshGateway { return fmt.Errorf("service image is required") } - if s.Port <= 0 { - return fmt.Errorf("service has invalid port") + if s.IsV2() { + if len(s.Ports) > 0 && s.Port > 0 { + return fmt.Errorf("cannot specify both singleport and multiport on service in v2") + } + if s.Port > 0 { + s.Ports = map[string]*Port{ + "legacy": { + Number: s.Port, + Protocol: "tcp", + }, + } + s.Port = 0 + } + + if !s.DisableServiceMesh && s.EnvoyPublicListenerPort > 0 { + s.Ports["mesh"] = &Port{ + Number: s.EnvoyPublicListenerPort, + Protocol: "mesh", + } + } + + for name, port := range s.Ports { + if port == nil { + return fmt.Errorf("cannot be nil") + } + if port.Number <= 0 { + return fmt.Errorf("service has invalid port number %q", name) + } + if port.ActualProtocol != pbcatalog.Protocol_PROTOCOL_UNSPECIFIED { + return fmt.Errorf("user cannot specify ActualProtocol field") + } + + proto, valid := Protocol(port.Protocol) + if !valid { + return fmt.Errorf("service has invalid port protocol %q", port.Protocol) + } + port.ActualProtocol = proto + } + } else { + if len(s.Ports) > 0 { + return fmt.Errorf("cannot specify mulitport on service in v1") + } + if s.Port <= 0 { + return fmt.Errorf("service has invalid port") + } + if s.EnableTransparentProxy { + return fmt.Errorf("tproxy does not work with v1 yet") + } } if s.DisableServiceMesh && s.IsMeshGateway { return fmt.Errorf("cannot disable service mesh and still run a mesh gateway") @@ -723,6 +945,12 @@ func (s *Service) Validate() error { if s.DisableServiceMesh && len(s.Upstreams) > 0 { return fmt.Errorf("cannot disable service mesh and configure upstreams") } + if s.DisableServiceMesh && len(s.ImpliedUpstreams) > 0 { + return fmt.Errorf("cannot disable service mesh and configure implied upstreams") + } + if s.DisableServiceMesh && s.EnableTransparentProxy { + return fmt.Errorf("cannot disable service mesh and activate tproxy") + } if s.DisableServiceMesh { if s.EnvoyAdminPort != 0 { @@ -748,6 +976,20 @@ func (s *Service) Validate() error { return fmt.Errorf("upstream local address is invalid: %s", u.LocalAddress) } } + if u.Implied { + return fmt.Errorf("implied field cannot be set") + } + } + for _, u := range s.ImpliedUpstreams { + if u.ID.Name == "" { + return fmt.Errorf("implied upstream service name is required") + } + if u.LocalPort > 0 { + return fmt.Errorf("implied upstream local port cannot be set") + } + if u.LocalAddress != "" { + return fmt.Errorf("implied upstream local address cannot be set") + } } return nil @@ -758,11 +1000,18 @@ type Upstream struct { LocalAddress string `json:",omitempty"` // defaults to 127.0.0.1 LocalPort int Peer string `json:",omitempty"` + + // PortName is the named port of this Upstream to route traffic to. + // + // This only applies for multi-port (v2). + PortName string `json:",omitempty"` // TODO: what about mesh gateway mode overrides? // computed at topology compile - Cluster string `json:",omitempty"` - Peering *PeerCluster `json:",omitempty"` // this will have Link!=nil + Cluster string `json:",omitempty"` + Peering *PeerCluster `json:",omitempty"` // this will have Link!=nil + Implied bool `json:",omitempty"` + VirtualPort uint32 `json:",omitempty"` } type Peering struct { diff --git a/testing/deployer/update-latest-versions.sh b/testing/deployer/update-latest-versions.sh new file mode 100755 index 000000000000..16f023142274 --- /dev/null +++ b/testing/deployer/update-latest-versions.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +set -euo pipefail + +unset CDPATH + +cd "$(dirname "$0")" + +### +# This script will update the default image names to the latest released versions of +# Consul, Consul Enterprise, and Consul Dataplane. +# +# For Envoy, it will interrogate the latest version of Consul for it's maximum supported +# Envoy version and use that. +### + +readonly consul_latest="hashicorp/consul:latest" +readonly dataplane_latest="hashicorp/consul-dataplane:latest" + +# First pull current versions of some images. +docker pull "$consul_latest" || true +docker pull "$dataplane_latest" || true + +# Read the version from the easy ones directly out of their image labels. +consul_version="$(docker image inspect "$consul_latest" | jq -r '.[0].Config.Labels."org.opencontainers.image.version"')" +dataplane_version="$(docker image inspect "$dataplane_latest" | jq -r '.[0].Config.Labels.version')" + +# Check to see what version of Envoy consul wants. +docker rm -f consul-envoy-check &>/dev/null || true +docker run -d --name consul-envoy-check "$consul_latest" + +envoy_version="" +while true; do + # We have to retry in case consul doesn't fully start up before we get here. + envoy_version="$(docker exec consul-envoy-check sh -c 'wget -q localhost:8500/v1/agent/self -O -' | jq -r '.xDS.SupportedProxies.envoy[0]')" + if [[ -n "$envoy_version" ]]; then + break + fi +done +docker rm -f consul-envoy-check &>/dev/null || true + +cat > topology/default_versions.go < ../api - -replace github.com/hashicorp/consul/envoyextensions => ../envoyextensions - -replace github.com/hashicorp/consul/proto-public => ../proto-public +replace ( + github.com/hashicorp/consul/api => ../api + github.com/hashicorp/consul/envoyextensions => ../envoyextensions +) exclude ( github.com/hashicorp/go-msgpack v1.1.5 // has breaking changes and must be avoided @@ -14,10 +13,10 @@ exclude ( ) require ( - github.com/envoyproxy/go-control-plane v0.11.0 + github.com/envoyproxy/go-control-plane v0.11.1 github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e - github.com/hashicorp/consul/api v1.24.0 - github.com/hashicorp/consul/envoyextensions v0.4.1 + github.com/hashicorp/consul/api v1.26.1 + github.com/hashicorp/consul/envoyextensions v0.5.1 github.com/stretchr/testify v1.8.3 google.golang.org/protobuf v1.30.0 ) @@ -25,9 +24,9 @@ require ( require ( github.com/armon/go-metrics v0.4.1 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect - github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195 // indirect + github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/envoyproxy/protoc-gen-validate v0.10.0 // indirect + github.com/envoyproxy/protoc-gen-validate v1.0.1 // indirect github.com/fatih/color v1.14.1 // indirect github.com/golang/protobuf v1.5.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -45,15 +44,17 @@ require ( github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 // indirect - golang.org/x/net v0.13.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.11.0 // indirect - google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect - google.golang.org/grpc v1.55.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e // indirect + google.golang.org/grpc v1.56.3 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/troubleshoot/go.sum b/troubleshoot/go.sum index b5f44a5e8f16..b487eb60a5f9 100644 --- a/troubleshoot/go.sum +++ b/troubleshoot/go.sum @@ -68,8 +68,8 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH 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-20230310173818-32f1caf87195 h1:58f1tJ1ra+zFINPlwLWvQsR9CzAKt2e+EWV2yX9oXQ4= -github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/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/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -81,13 +81,13 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m 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.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.0 h1:jtLewhRR2vMRNnq2ZZUoCjUlgut+Y0+sDDWPOfwOi1o= -github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI= +github.com/envoyproxy/go-control-plane 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/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e h1:g8euodkL4GdSpVAjfzhssb07KgVmOUqyF4QOmwFumTs= github.com/envoyproxy/go-control-plane/xdsmatcher v0.0.0-20230524161521-aaaacbfbe53e/go.mod h1:/NGEcKqwNq3HAS2vCqHfsPx9sJZbkiNQ6dGx9gTE/NA= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.10.0 h1:oIfnZFdC0YhpNNEX+SuIqko4cqqVZeN9IGTrhZje83Y= -github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss= +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/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= @@ -162,7 +162,7 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/hashicorp/consul/sdk v0.14.1 h1:ZiwE2bKb+zro68sWzZ1SgHF3kRMBZ94TwOCFRF4ylPs= +github.com/hashicorp/consul/sdk v0.15.0 h1:2qK9nDrr4tiJKRoxPGhm6B7xJjLVIQqkjiab2M4aKjU= 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= @@ -266,8 +266,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1: 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.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +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.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -378,8 +378,8 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +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= @@ -438,8 +438,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.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/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= @@ -448,8 +448,8 @@ 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.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/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= @@ -551,8 +551,12 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D 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-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= -google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw= +google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e h1:AZX1ra8YbFMSb7+1pI8S9v4rrgRR7jU1FmuFSSjTVcQ= +google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e h1:NumxXLPfHSndr3wBBdeKiVHjGVFzi9RX2HwwQke94iY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= 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= @@ -569,8 +573,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= 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= diff --git a/ui/.nvmrc b/ui/.nvmrc index b6a7d89c68e0..3c032078a4a2 100644 --- a/ui/.nvmrc +++ b/ui/.nvmrc @@ -1 +1 @@ -16 +18 diff --git a/ui/package.json b/ui/package.json index 5a161e4e691b..7ed39b1595ac 100644 --- a/ui/package.json +++ b/ui/package.json @@ -24,6 +24,6 @@ "ember-basic-dropdown": "3.0.21" }, "engines": { - "node": ">=14 <=16" + "node": "18" } } diff --git a/ui/packages/consul-lock-sessions/app/components/consul/lock-session/list/index.hbs b/ui/packages/consul-lock-sessions/app/components/consul/lock-session/list/index.hbs index 247b0dd8fc9d..465c0721ec7b 100644 --- a/ui/packages/consul-lock-sessions/app/components/consul/lock-session/list/index.hbs +++ b/ui/packages/consul-lock-sessions/app/components/consul/lock-session/list/index.hbs @@ -14,7 +14,7 @@ as |item index|> {{else}} {{item.ID}} - @@ -28,7 +28,7 @@ as |item index|> ID
- diff --git a/ui/packages/consul-peerings/app/components/consul/peer/address/list/index.hbs b/ui/packages/consul-peerings/app/components/consul/peer/address/list/index.hbs index bc6294e015f0..aabada41ad10 100644 --- a/ui/packages/consul-peerings/app/components/consul/peer/address/list/index.hbs +++ b/ui/packages/consul-peerings/app/components/consul/peer/address/list/index.hbs @@ -18,7 +18,7 @@
{{address}}
-
- diff --git a/ui/packages/consul-ui/app/components/code-editor/index.js b/ui/packages/consul-ui/app/components/code-editor/index.js index 72e3abf8eb8a..65566d159b76 100644 --- a/ui/packages/consul-ui/app/components/code-editor/index.js +++ b/ui/packages/consul-ui/app/components/code-editor/index.js @@ -36,22 +36,24 @@ export default Component.extend({ } }, setMode: function (mode) { - let options = { - ...DEFAULTS, - mode: mode.mime, - readOnly: this.readonly, - }; - if (mode.name === 'XML') { - options.htmlMode = mode.htmlMode; - options.matchClosing = mode.matchClosing; - options.alignCDATA = mode.alignCDATA; - } - set(this, 'options', options); + if (!this.isDestroying && !this.isDestroyed) { + let options = { + ...DEFAULTS, + mode: mode.mime, + readOnly: this.readonly, + }; + if (mode.name === 'XML') { + options.htmlMode = mode.htmlMode; + options.matchClosing = mode.matchClosing; + options.alignCDATA = mode.alignCDATA; + } + set(this, 'options', options); - const editor = this.editor; - editor.setOption('mode', mode.mime); - this.helper.lint(editor, mode.mode); - set(this, 'mode', mode); + const editor = this.editor; + editor.setOption('mode', mode.mime); + this.helper.lint(editor, mode.mode); + set(this, 'mode', mode); + } }, willDestroyElement: function () { this._super(...arguments); diff --git a/ui/packages/consul-ui/app/components/copy-button/README.mdx b/ui/packages/consul-ui/app/components/consul-copy-button/README.mdx similarity index 93% rename from ui/packages/consul-ui/app/components/copy-button/README.mdx rename to ui/packages/consul-ui/app/components/consul-copy-button/README.mdx index 7f45737fdb78..c207545f30f1 100644 --- a/ui/packages/consul-ui/app/components/copy-button/README.mdx +++ b/ui/packages/consul-ui/app/components/consul-copy-button/README.mdx @@ -1,4 +1,4 @@ -# CopyButton +# ConsulCopyButton Button component used for copy-to-clipboard functionality so the user can easily copy specified text to their clipboard, along with tooltip-like notifications so the user has some sort of feedback to know the value has been copied. @@ -10,7 +10,7 @@ Can be used inline to render only a small icon for the button with no other text
Icon only
- @@ -20,12 +20,12 @@ Can be used inline to render only a small icon for the button with no other text
Icon and text
- Copy me! - +
``` diff --git a/ui/packages/consul-ui/app/components/copy-button/chart.xstate.js b/ui/packages/consul-ui/app/components/consul-copy-button/chart.xstate.js similarity index 100% rename from ui/packages/consul-ui/app/components/copy-button/chart.xstate.js rename to ui/packages/consul-ui/app/components/consul-copy-button/chart.xstate.js diff --git a/ui/packages/consul-ui/app/components/copy-button/index.hbs b/ui/packages/consul-ui/app/components/consul-copy-button/index.hbs similarity index 76% rename from ui/packages/consul-ui/app/components/copy-button/index.hbs rename to ui/packages/consul-ui/app/components/consul-copy-button/index.hbs index ed3b42388cd3..ace1ff323223 100644 --- a/ui/packages/consul-ui/app/components/copy-button/index.hbs +++ b/ui/packages/consul-ui/app/components/consul-copy-button/index.hbs @@ -14,12 +14,12 @@ {{#let (fn dispatch 'SUCCESS') (fn dispatch 'ERROR') (fn dispatch 'RESET') as |success error reset|}}